无法在Spring Boot中拦截ApplicationEnvironmentPreparedEvent

时间:2018-02-17 01:54:38

标签: spring-boot

我需要以编程方式设置一些系统属性,并且我认为最好的方法是在拦截ApplicationEnvironmentPreparedEvent后在事件监听器中执行此操作。 但问题是我无法在听众中捕捉到这一事件。

@Component
public class AppListener {

    @EventListener
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", MyThreadFactory.class.getName());
        }
    }

}

我做错了什么以及为什么我不能抓住那个事件?

2 个答案:

答案 0 :(得分:0)

来自Spring Boot documentation

  

某些事件实际上是在ApplicationContext被创建之前触发的   创建的,所以您不能将这些监听器注册为@Bean。您   可以使用SpringApplication.addListeners(...)方法注册它们   或SpringApplicationBuilder.listeners(…)方法。

Spring documentation(对于5.1.7版本而言):

  

@EventListener批注的处理通过内部   自动注册的EventListenerMethodProcessor bean   使用Java配置或通过    或元素何时   使用XML配置。

因此,ApplicationEnvironmentPreparedEvent(以及所有Spring Boot应用程序事件)在上下文和bean创建之前发生,并且@EventListener由bean控制,因此此时@EventListener注释不能被拾取。您将必须专门创建一个侦听器类并显式添加它以捕获此事件(或在bean创建之前发生的任何事件)。

您的课程:

public class AppListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>
{
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event)
    {
        System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory",
                MyThreadFactory.class.getName());
    }
}

...以及相关的SpringApplicationBuilder代码:

ConfigurableApplicationContext context = new SpringApplicationBuilder(Launcher.class)
            .listeners(new AppListener()).run();

答案 1 :(得分:-1)

您需要为此事件专门实现ApplicationListener接口

@Component
public class AppListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", MyThreadFactory.class.getName());
        }

    }
}