Spring 4.1x,SimpleNamingContextBuilder 和@Value("#{environment.xxx}")
Spring 4.1x, SimpleNamingContextBuilder and @Value("#{environment.xxx}")
到目前为止,我一直在使用 Spring 4.0.8,以下版本运行良好:
在我的单元测试中,我在 jndi 环境中设置了一个值:
SimpleNamingContextBuilder _simpleNamingContextBuilder =
new SimpleNamingContextBuilder();
_simpleNamingContextBuilder.bind(
"java:comp/env/myBoolVar", true);
_simpleNamingContextBuilder.activate();
然后在我的 class 中,我这样访问它:
@Value("#{environment.myBoolVar}")
private Boolean _myBoolVar = Boolean.FALSE;
我已经升级到 Spring 4.1.2,但它不再有效。始终使用默认值 false,因为 Spring 无法找到该值。
如果我使用旧方式访问这个值:
@Resource(mappedName = "java:comp/env/myBoolVar")
确实有效。
我一直在搜索 SO 和整个网络,我看到了大量的信息,但是 none 帮助我解决了这个问题。我的理解是 Spring 环境可以访问 @Value 所做的所有值。所以我不确定是什么问题。
仅供在此苦苦挣扎的任何人参考。最后,我把将 "myBoolVar" 值添加到 SimpleNamingContextBuilder 的代码放在一个带有 @BeforeClass 注释的方法中,现在它工作正常。
基本上发生的事情是,在启动时 Spring 试图在 StandardServletEnvironment.customizePropertySources() 方法中整理出它拥有的 PropertySources。当需要查找 jndiProperties 时,它会执行以下操作:
if(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource("jndiProperties"));
}
该方法 JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable() 执行以下操作:
try {
new InitialContext().getEnvironment();
return true;
}
catch (Throwable ex) {
return false;
}
在我的例子中,对 getEnvironment() 的调用抛出了 NoInitialContextException:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
这阻止了 Spring 创建 jndiProperties PropertySource,因此我的布尔变量丢失了。
所以我开始在网上寻找发生这种情况的原因......但后来在 Spring 论坛上发现 old article 说这将我的代码放在 @BeforeClass 块中,等等瞧。
我希望这能在未来的某个时候为某人免去一些痛苦。
到目前为止,我一直在使用 Spring 4.0.8,以下版本运行良好:
在我的单元测试中,我在 jndi 环境中设置了一个值:
SimpleNamingContextBuilder _simpleNamingContextBuilder =
new SimpleNamingContextBuilder();
_simpleNamingContextBuilder.bind(
"java:comp/env/myBoolVar", true);
_simpleNamingContextBuilder.activate();
然后在我的 class 中,我这样访问它:
@Value("#{environment.myBoolVar}")
private Boolean _myBoolVar = Boolean.FALSE;
我已经升级到 Spring 4.1.2,但它不再有效。始终使用默认值 false,因为 Spring 无法找到该值。
如果我使用旧方式访问这个值:
@Resource(mappedName = "java:comp/env/myBoolVar")
确实有效。
我一直在搜索 SO 和整个网络,我看到了大量的信息,但是 none 帮助我解决了这个问题。我的理解是 Spring 环境可以访问 @Value 所做的所有值。所以我不确定是什么问题。
仅供在此苦苦挣扎的任何人参考。最后,我把将 "myBoolVar" 值添加到 SimpleNamingContextBuilder 的代码放在一个带有 @BeforeClass 注释的方法中,现在它工作正常。
基本上发生的事情是,在启动时 Spring 试图在 StandardServletEnvironment.customizePropertySources() 方法中整理出它拥有的 PropertySources。当需要查找 jndiProperties 时,它会执行以下操作:
if(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource("jndiProperties"));
}
该方法 JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable() 执行以下操作:
try {
new InitialContext().getEnvironment();
return true;
}
catch (Throwable ex) {
return false;
}
在我的例子中,对 getEnvironment() 的调用抛出了 NoInitialContextException:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
这阻止了 Spring 创建 jndiProperties PropertySource,因此我的布尔变量丢失了。
所以我开始在网上寻找发生这种情况的原因......但后来在 Spring 论坛上发现 old article 说这将我的代码放在 @BeforeClass 块中,等等瞧。
我希望这能在未来的某个时候为某人免去一些痛苦。