Spring 的 @DependsOn 不适用于应用程序事件?

gor*_*tde 3 java spring

我有一个发送应用程序事件的类。接收者不能错过这个事件,因此发送者依赖于接收者。

@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");
   }
}
Run Code Online (Sandbox Code Playgroud)

在调试模式下,您可以看到它Sender在之后初始化Receiver,这应该导致接收方始终捕获发送方的事件 - 但事实并非如此。

事实上,在初始化接收器和准备接收事件之间似乎存在延迟。如果我在发送方中延迟发布事件几毫秒,接收方就会按预期捕获它。

因此,似乎并@DependsOn不能完全确保接收器在发送者之前完全初始化,这与记录的内容完全相反。

如何在不使用任何难看的延迟的情况下实现接收者捕获事件?

Ale*_*can 5

正如@M。Deinum 建议,您面临的问题是应用程序上下文当时尚未准备好侦听事件。

触发的事件可以在 BeanFactoryPostProcessor( DefaultListableBeanFactory.preInstantiateSingletons() ) 完成后进行处理。您的 postConstruct 注释在 BeanFactoryPostProcessor 被调用之前被调用,这会导致事件处理的丢失。(参考spring bean 生命周期

作为解决方案,您的 bean 可以在 applicationContext 启动时触发事件(ContextRefreshedEvent

    @Service
    class Sender {

        @Autowired
        private ApplicationEventPublisher applicationEventPublisher;

        @EventListener
        public void applicationStarted(ContextRefreshedEvent event) {
            applicationEventPublisher.publishEvent(new MyEvent());
        }


    }
Run Code Online (Sandbox Code Playgroud)