Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ApplicationContext events never been thrown

Tags:

java

spring

I'm trying to have ContextEventListener on all ContextXXXEvent I created a listener for each event type as following (the ContextRefreshedEvent is an Example):

@Component
public class MyApplicationRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    logger.info(getClass(), "Event source [{}]", event.getSource());
  }

}

Both ContextRefreshedEvent and ContextClosedEvent were caught and their listeners did the expected job.

I tried to do the same for ContextStartedEvent and ContextClosedEvent but both of these two events listeners were not caught.

The event.getSource printed (in the refreshed and closed events):

Event source [Root WebApplicationContext: startup date [Tue May 09 10:07:51 IDT 2017]; root of context hierarchy]

Is there any difference between (started and stopped) and (refreshed and closed)?

Is it because my application context is WebApplicationContext (as the event.getSource() shows?)

like image 391
Marwan Jaber Avatar asked May 09 '17 07:05

Marwan Jaber


1 Answers

I have gone through spring code. I will discuss about ContextStartedEvent. Similar explanation can be given for stopped event.

Explanation:

ContextStartedEvent is emitted only from start() method of AbstractApplicationContext and nowhere. Since you are not able to catch the ContextStartedEvent, if we can know who calls or doesn't call this method we can find the answer.

In spring, applicationContext can be started in two ways. One, we explicitly call this method start() which will trigger the initialisation of beans in the context and rest of the context initialisation. The other way is for spring to take care of the context initialisation. In other words, we don't deal with context start and stop this way. Almost all of us unknowingly use the second way of initialisation. For example, you must be using xml files to load bean definitions which uses ClassPathXmlApplicationContext. This is inherited from AbstractRefreshableApplicationContext.

Hence I think ContextStartedEvent and ContextStoppedEvent are emitted only if you start and stop (manage) the ApplicationContext manually. There are another set of ApplicationContext implementations which you can use to manage ApplicationContext on your own. I haven't tried them out personally. I will update the answer if I am successfully able to do this.

A similar explanation can be given to ContextStoppedEvent.

Update: This is inline with the definitions of the events provided in the spring docs (as well as the other answer to this question by @coolgirl)

like image 71
yaswanth Avatar answered Sep 28 '22 01:09

yaswanth