SpringBoot事件监听器无法接收事件。

10

我的EventListener注解没有接收到任何Spring事件。这是我的代码:

@Component
public class ProxyConfig {

    public ProxyConfig() {
        System.out.println("I can see this in the console");
    }

    @EventListener
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        System.out.println("WON'T WORK :-(");  // FIXME
    }

    @EventListener
    public void test(ApplicationStartedEvent event) {
        System.out.println("WON'T WORK :-(");  // FIXME
    }
}

这是我的 Application 类:

@SpringBootApplication
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyApp.class, args);
    }
}

根据https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2https://solidsoft.wordpress.com/2015/09/29/annotation-driven-event-listeners-in-spring-4-2/,它应该可以工作,但仍然无法打印我的"WON'T WORK :-("字符串 :(
有什么想法吗?
谢谢!

ApplicationProxyConfig在哪些包中? - Andy Wilkinson
Application位于包com.mycompany.app中。而ProxyConfig则在子包com.mycompany.app.configuration.impl中。 - user6479676
通过创建一个 META-INF/spring.factories 文件(参见 http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-application-events-and-listeners),可以在没有注释的情况下运行,但是有注释就不行了... :( - user6479676
我刚刚注意到你正在监听的事件。这是预期的行为。我已经在下面的答案中尝试解释正在发生的事情。 - Andy Wilkinson
2个回答

12

你要监听的两个事件都是在应用程序生命周期的早期发布的。

ApplicationStartedEvent会在“SpringApplication启动后尽可能早地发送, 在环境或ApplicationContext可用之前但在ApplicationListeners注册后”。

ApplicationEnvironmentPreparedEvent被发布于“当SpringApplication正在启动且Environment第一次可用于检查和修改时”。

在这两种情况下,事件发布得太早了,因此无法通过注释和应用程序上下文找到侦听器。像你观察到的那样,你可以使用spring.factories来注册你的监听器。另外,你也可以使用SpringApplication的setter方法。


1
如何通过SpringApplication的setter方法实现? - gstackoverflow
可以尝试使用 ApplicationReadyEvent - Dimitar II

1

这个问题虽然很老,但对于任何遇到同样问题的人来说...

我刚刚花费了几个小时处理完全相同的问题,我在互联网上搜索并进行了无数次测试,但都无济于事,我尝试使用 @EventListener(ApplicationReadyEvent.class)@PostConstruct 进行注释,但仍然没有作用。

我的理念是,当简单的方法不起作用且互联网无法提供帮助时,这意味着你搞乱了某些东西。所以我开始检查我的代码,我看到您犯了和我一样的错误。

您从别处复制了示例或将原始配置类从 MyApp 更改为 Application,但您忘记更改以下行:

SpringApplication.run(MyApp.class, args);

为了

SpringApplication.run(Application.class, args);

第一行不会有任何作用,除非 MyApp 也有 @SpringBootApplication 或其他配置注解,第二行将找到 @SpringBootApplication 注解并正确启动 Spring Boot 应用程序。

顺便说一下,@EventListener(ApplicationReadyEvent.class)@PostConstruct 都可以正常工作,在 Java 17 上测试过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接