无法在 Spring Boot 中拦截 ApplicationEnvironmentPreparedEvent

Iho*_* M. 5 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());
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我做错了什么,为什么我不能赶上那个事件?

Jas*_*son 8

Spring Boot 文档

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

来自Spring 文档(适用于 5.1.7 版):

@EventListener 注释的处理是通过内部 EventListenerMethodProcessor bean 执行的,该 bean 在使用 Java 配置时自动注册,或在使用 XML 配置时通过 or 元素手动注册。

所以 ApplicationEnvironmentPreparedEvent(以及所有 Spring Boot 应用事件)发生在 context 和 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

ConfigurableApplicationContext context = new SpringApplicationBuilder(Launcher.class)
            .listeners(new AppListener()).run();
Run Code Online (Sandbox Code Playgroud)


小智 -3

您需要专门为此事件实现 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());
        }

    }
}
Run Code Online (Sandbox Code Playgroud)