我正在尝试在Spring MVC中发布自定义事件,但在上下文加载时没有触发,下面是代码片段,
onConnectionOpened将在连接到使用@PostConstruct
@Autowired
private ApplicationEventPublisher publisher;
public void onConnectionOpened(EventObject event) {
publisher.publishEvent(new StateEvent("ConnectionOpened", event));
}
我在侦听器部分使用注释,如下所示
@EventListener
public void handleConnectionState(StateEvent event) {
System.out.println(event);
}
我能够看到在加载或刷新上下文后触发的事件,是否可以在加载或刷新上下文后发布自定义应用程序事件?
我正在使用Spring 4.3.10
提前致谢
答案 0 :(得分:3)
@EventListener
注释由EventListenerMethodProcessor
处理,只要所有bean都被实例化并准备就绪,它将立即运行。当您从@PostConstruct
带注释的方法发布事件时,可能并非当时所有内容都已启动并运行,并且尚未检测到基于@EventListener
的方法。
相反,您可以使用ApplicationListener
界面来获取事件并处理它们。
public class MyEventHandler implements ApplicationListener<StateEvent> {
public void onApplicationEvent(StateEvent event) {
System.out.println(event);
}
}
答案 1 :(得分:0)
您应该在ContextRefreshedEvent发生后发布事件,但是如果您在@PostConstruct中等待ContextRefreshedEvent,它将使整个应用程序挂起,因此使用@Async
将解决此问题。
@EnableAsync
@SpringBootApplication
public class YourApplication
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
@Slf4j
@Service
public class PublishHelper {
private final ApplicationEventPublisher publisher;
private final CountDownLatch countDownLatch = new CountDownLatch(1);
@EventListener(classes = {ContextRefreshedEvent.class})
public void eventListen(ContextRefreshedEvent contextRefreshedEvent) {
log.info("publish helper is ready to publish");
countDownLatch.countDown();
}
public PublishHelper(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Async
@SneakyThrows
public void publishEvent(Object event) {
countDownLatch.await();
publisher.publishEvent(event);
}
}