在上下文加载之前无法在spring中发布自定义事件

时间:2017-11-13 18:51:31

标签: java spring spring-mvc spring-annotations

我正在尝试在Spring MVC中发布自定义事件,但在上下文加载时没有触发,下面是代码片段,

onConnectionOpened将在连接到使用@PostConstruct 初始化bean之后触发的服务器之后被调用

@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

提前致谢

2 个答案:

答案 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);
    }
}