问题
I am trying to publish a custom event in Spring MVC, but is is not firing while context is loading, below are the code snippet,
The onConnectionOpened will be called after connecting to a server which is triggered after bean initialization using @PostConstruct
@Autowired
private ApplicationEventPublisher publisher;
public void onConnectionOpened(EventObject event) {
publisher.publishEvent(new StateEvent("ConnectionOpened", event));
}
I am using annotation in listener part as below
@EventListener
public void handleConnectionState(StateEvent event) {
System.out.println(event);
}
I am able to see events fired after the context is loaded or refreshed, is this expected that custom application events can be published after the context loaded or refreshed?.
I am using Spring 4.3.10
Thanks in advance
回答1:
The @EventListener
annotations are processed by the EventListenerMethodProcessor which will run as soon as all beans are instantiated and ready. As you are publishing an event from a @PostConstruct
annotated method it might be that not everything is up and running at that moment and @EventListener
based methods haven't been detected yet.
Instead what you can do is use the ApplicationListener interface to get the events and process them.
public class MyEventHandler implements ApplicationListener<StateEvent> {
public void onApplicationEvent(StateEvent event) {
System.out.println(event);
}
}
回答2:
You should publish event after ContextRefreshedEvent occur, but if you wait ContextRefreshedEvent in @PostConstruct, it will make whole applicaiton hang up, so use @Async
will solve this problem.
@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);
}
}
来源:https://stackoverflow.com/questions/47271498/not-able-to-publish-custom-event-in-spring-before-context-load