Spring Singletons and Lifecycle Annotations

A small snippet of code to help me present the topic


@Service(name="singletonServiceBean")
@Scope(value = "singleton") //this is the default value. Explicitly setting it just for readability.
public class SingletonServiceBean {

      private Logger logger = LoggerFactory.getLogger(SingletonServiceBean.class);

      public SingletonServiceBean() {
         logger.debug("Constructor called for the service bean");
      }

      @PostConstruct
      public void initialize() {
         logger.debug("Initialize the bean in PostConstruct");
      }
}

About Singleton Beans -
After you create an application context you will notice the constructor getting called twice sometimes even if the bean is declared as singleton. The reason is – spring aop is proxy-based, i.e. the container creates ‘raw’ bean instance and proxy for it if the bean is affected by AOP rules. If you use cglib-based proxies than the proxy class is created at runtime via subclassing original bean class. So, when proxy object is created, it calls superclass constructor and it looks as two instances are created

@PostConstruct and @Predestroy- Some introduction on this

The @PostConstruct and @PreDestroy annotations(introduced with Spring 2.5) can be used to trigger Spring initialization and destruction callbacks respectively. This feature extends but does not replace the two options –  i. implementing Spring’s InitializingBean and DisposableBean interfaces
ii. explicitly declaring “init-method” and “destroy-method” attributes of the ‘bean’ element in xml. This explicit configuration is sometimes necessary, such as when the callbacks need to be invoked on code that is outside of the developer’s control. For e.g. – when a third party DataSource is used, a ‘‘destroy-method’ is declared explicitly.

To enable these lifecycle annotations we need to just add the below tag in the spring xml

<context:annotation-config/>

There are two reasons of using the @PostConstruct annotation instead of using a constructor
1. because when the constructor is called, the bean is not yet initialized – i.e. no dependencies are injected. In the @PostConstruct method the bean is fully initialized and you can use the dependencies.

2. because this is the contract that guarantees that this method will be invoked only once in the bean lifecycle. It may happen (like in the singletonServiceBean example above) that a bean is instantiated multiple times by the container in its internal working, but it guarantees that @PostConstruct will be invoked only once.

One interesting point of the annotation-based lifecycle callbacks is that more than one method may carry either annotation, and all annotated methods will be invoked

About these ads

Posted on April 16, 2011, in spring and tagged . Bookmark the permalink. 8 Comments.

  1. Hello Amit!

    then, how I can use @PostConstruct on a spring bean method without being called twice?

    Anyway, thanks for sharing, it was helpful to me :)

    • Thanks for the comment. I didn’t understand what you wanted to say. If @PostConstruct is added on any method of a spring bean, Spring will guarantee that the method is called just once instead of the constructor which could get called more then once as I explained above.

  2. Hi again!

    Ok, I finally get it ;) my problem was that my @PostConstruct method was calling twice in my application, so i’ve readed your blog post and I understood you got the same problem. Now, I realize that you meant ‘Constructor’, not @PostConstruct method, i had read it wrong.

    My problem was about configuration. I use 2 application config (one for application, another for mvc) and my controllers were accidentally included twice. For this reason, @PostConstruct methods were calling twice! I have excluded the controllers in app config and now works perfectly !

    Thanks for the answer, you helped me to find my problem! :)

  3. Hi.
    I need to create a threadpool that has X number of threads, depending on configuration file.
    Therefore, I want to created a singleton, with postConstruct annotation that will initialize the pool with the number of threads.
    So, how can I pass parameters to this method? and how can I take those parameters for a file?
    thank you for your time…
    Issahar.

    • There are various options. You could use constructor based injection or you could load the configuration file in a java.util.Properties class instance assuming the config file is a properties file.

      Does that help?

  4. I’m still facing this issue though I have the following defined in my spring.xml

  5. I’m still facing this issue though I have the following – ” ” defined in my spring.xml

  6. Hi,
    Sorry. Please ignore my last 2 posts.My concern is I’m still facing this issue though I have the following – ”context-component-scan ” defined in my spring.xml

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 33 other followers

%d bloggers like this: