我有一个发送应用程序事件的类。接收方不得错过此事件,因此发送方依赖于接收方。
@Service
@DependsOn("receiver")
class Sender {
...
@PostConstruct
public void init(){
applicationEventPublisher.publishEvent(new MyEvent());
}
}
@Service
class Receiver {
...
@EventListener
public void onEvent(MyEvent event) {
System.out.println("Event catched");
}
}
在调试模式下,您可以看到在Sender
之后初始化Receiver
,这会导致Receiver始终捕获发件人的事件 - 但它不是。
事实上,在初始化接收器和准备接收事件的点之间似乎存在延迟。如果我延迟在发件人中发布事件几毫秒,接收器就会按预期捕获它。
所以似乎@DependsOn
并不能完全确定Seceiver在发送者之前完全初始化,这与记录的完全相反。
如何实现接收器在不使用任何丑陋延迟的情况下捕获事件?
答案 0 :(得分:2)
作为@M。 Deinum建议,您面临的问题是,应用程序上下文在此时尚未准备好收听事件。
BeanFactoryPostProcessor(DefaultListableBeanFactory.preInstantiateSingletons())完成后,可以对触发的事件进行处理。在调用BeanFactoryPostProcessor之前调用postConstruct注释,这会导致事件处理丢失。(参考spring bean lifecycle)
作为解决方案,当applicationContext启动时,bean可以触发事件(ContextRefreshedEvent)
@Service
class Sender {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@EventListener
public void applicationStarted(ContextRefreshedEvent event) {
applicationEventPublisher.publishEvent(new MyEvent());
}
}