我需要以编程方式设置一些系统属性,我认为最好的方法是在事件侦听器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)
我做错了什么,为什么我不能赶上那个事件?
某些事件实际上是在创建 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)
| 归档时间: |
|
| 查看次数: |
2412 次 |
| 最近记录: |