我有一个Spring Boot应用程序,我的目的是为上下文应用程序属性定义的应用程序设置defualt Locale,示例值为:en-US
。
它在启动应用程序正常启动时工作正常,我在这里粘贴工作监听器的相关代码。
应用程序的主要类(只是相关部分):
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.mypackage"})
@ImportResource(value = {
//some xml file imports were here, not really relevant
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
监听器(com.mypackage.MyApplicationContextEventListener):
@Component
public class MyApplicationContextEventListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
String localeSpecifier = event.getApplicationContext().getEnvironment().getProperty("app.locale");
System.out.println("locale in event listener: " + localeSpecifier);
if (localeSpecifier != null) {
Locale.setDefault(Locale.forLanguageTag(localeSpecifier));
}
}
}
application.properties:
app.locale=en-US
成功启动应用程序后的输出:
事件监听器中的语言环境:en-US
然而,我不能在单元测试中得到相同的工作,我有一个复杂的单元测试,但为了简单起见,我创建了一个更简洁的专用测试类,可以重现故障。 不幸的是,在这个问题上花了好几个小时后,在ApplicationListener中收到ContextRefreshed事件时,我仍然无法弄清楚为什么应用程序属性不可用(来自应用程序上下文)。
以下是测试类的代码:
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ContextConfiguration(locations = {
"classpath*:test-spring/test-service-context.xml"
})
public class Test {
@Value("${app.locale}")
protected String localeStr;
@Test
public void test1() {
System.out.println("locale in test1" + localeStr);
}
}
导入的test-service-context.xml的内容(bean组件扫描和测试属性的导入):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mypackage" use-default-filters="true">
<context:exclude-filter type="regex" expression=".*Application"/>
</context:component-scan>
<!-- some inrelevant imports are not listed here -->
<!-- IMPORT THE TEST PROPERTIES-->
<import resource="classpath*:test-spring/test-properties.context.xml"/>
</beans>
test-properties.context.xml的内容:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="locations">
<array>
<value>classpath:test-application.properties</value>
</array>
</property>
</bean>
</beans>
最后,test-application.properties的内容:
app.locale=en-US
运行测试后,输出如下:
事件监听器中的语言环境:null
test1 *** en-US中的语言环境
该属性被正确地注入到localeStr字段中(令人惊讶)但您可以看到它在侦听器的onEvent方法范围内未被解析(null)。
很明显,事件监听器(不知何故)无法访问上下文的属性(没有一个,我尝试过其他人而不是&#39; app.locale&#39;)以防万一我运行单元测试,但如果我运行启动应用程序,一切都很好,如上所述。
请注意,我不在监听器中引入空检查的主要原因是我希望保留“缺少应用程序属性”的可见性。喜欢将来运行时的问题。
感谢任何帮助,谢谢!