有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法在Spring Boot应用程序的ApplicationListener中获取应用程序属性

我有一个Spring启动应用程序,我的目的是为我的应用程序设置由上下文应用程序属性定义的defualt区域设置,示例值为: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));
      }

    }
}

应用程序。特性:

app.locale=en-US

成功启动应用程序后的输出:

locale in event listener: en-US

然而,我无法在单元测试中得到同样的工作,我有一个复杂的单元测试,但为了简单起见,我创建了一个专用的测试类,它更简洁,可以重现错误。 不幸的是,在花了数小时研究这个问题之后,我仍然无法理解为什么在ApplicationListener中接收到ContextRefresh事件时应用程序属性(从应用程序上下文)不可用

以下是测试类的代码:

@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);
    }
}

导入的测试服务上下文的内容。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>

测试属性的内容。上下文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>

最后介绍了测试应用的内容。特性:

app.locale=en-US

运行测试后,输出如下所示:

locale in event listener: null
locale in test1***en-US

该属性被正确地注入localeStr字段(令人惊讶),但您可以看到它在侦听器的onEvent方法的作用域中没有解析(null)

因此,很明显,如果我运行单元测试,事件侦听器(不知何故)无法访问上下文的属性(没有任何属性,我尝试了“app.locale”以外的其他属性),但是如果我运行启动应用程序,如上所述,一切正常

请注意,我不在侦听器中引入空检查的主要原因是我希望在将来的运行时保留“缺少应用程序属性”之类问题的可见性

感谢您的帮助,谢谢


共 (0) 个答案