47

I have the following ApplicationListener:

package org.mycompany.listeners;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;

public class MyApplicationListener implements ApplicationListener<ContextStartedEvent> {

  public MyApplicationListener() {
    super();
    System.out.println("Application context listener is created!");
  }

  /**
   * {@inheritDoc}
   */
  public void onApplicationEvent(final ContextStartedEvent event) {
    System.out.println("Context '" + event.getApplicationContext().getDisplayName() + "' is started!");
  }

}

And the following bean definition:

<bean name="myApplicationListener" class="org.mycompany.listeners.MyApplicationListener" />

I can see that bean is created as message from the constructor is printed, but context start event is never recieved. What am I missing?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Andrey Adamovich
  • 20,285
  • 14
  • 94
  • 132

3 Answers3

68

ContextStartedEvent is published when you explicitly invoke ConfigurableApplicationContext.start() on the context. If you need an event that is published when context is initialized, use ContextRefreshedEvent.

See also:

Henrik Aasted Sørensen
  • 6,966
  • 11
  • 51
  • 60
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 8
    Note that `ContextRefreshedEvent` may be published more than once, and therefore it may be also published before all the beans are initialized (e.g. when using CXF 2.4.2...). However, in most common setup, `ContextRefreshedEvent` will be indeed published only when contexted startup is finished. – Piotr Findeisen Feb 29 '12 at 15:33
  • 1
    very helpful but this conventions looks inappropriate :( – Sagar balai Sep 28 '18 at 19:28
7

Since you have no lazy loaded beans (according to you) then you are most likely using events for the wrong reason and probably should use something like InitializingBean interface instead:

public class MyBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        // ...
    }

}

From Spring manual:

To interact with the container's management of the bean lifecycle, you can implement the Spring InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the former and destroy() for the latter to allow the bean to perform certain actions upon initialization and destruction of your beans. You can also achieve the same integration with the container without coupling your classes to Spring interfaces through the use of init-method and destroy method object definition metadata.

Source: Spring Framework - Lifecycle callbacks

Mike Minicki
  • 8,216
  • 11
  • 39
  • 43
  • I think the afterPropertiesSet method applies to a single bean, not to the whole spring application context. http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/beans/factory/InitializingBean.html – Alina Danila Nov 04 '13 at 09:57
0

Not sure if this helps, but I vaguely remember having a similar problem, which was solved by preloading and not lazy loading. Here's a quick overview of both

lkamal
  • 3,788
  • 1
  • 20
  • 34
qwerty
  • 3,801
  • 2
  • 28
  • 43