How to call a method after bean initialization is complete?

334,890

Solution 1

You can use something like:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

This will call the "init" method when the bean is instantiated.

Solution 2

To expand on the @PostConstruct suggestion in other answers, this really is the best solution, in my opinion.

  • It keeps your code decoupled from the Spring API (@PostConstruct is in javax.*)
  • It explicitly annotates your init method as something that needs to be called to initialize the bean
  • You don't need to remember to add the init-method attribute to your spring bean definition, spring will automatically call the method (assuming you register the annotation-config option somewhere else in the context, anyway).

Solution 3

There are three different approaches to consider, as described in the reference

Use init-method attribute

Pros:

  • Does not require bean to implement an interface.

Cons:

  • No immediate indication in source code that this method is required after construction to ensure the bean is correctly configured.

Implement InitializingBean

Pros:

  • No need to specify init-method, or turn on component scanning / annotation processing.
  • Appropriate for beans supplied with a library, where we don't want the application using this library to concern itself with bean lifecycle.

Cons:

  • More invasive than the init-method approach.

Use JSR-250 @PostConstruct lifecyle annotation

Pros:

  • Useful when using component scanning to autodetect beans.
  • Makes it clearer that a specific method is to be used for initialisation. Intent is closer to the code.

Cons:

  • Initialisation no longer centrally specified in configuration.
  • You must remember to turn on annotation processing (which can sometimes be forgotten)

Solution 4

Have you tried implementing InitializingBean? It sounds like exactly what you're after.

The downside is that your bean becomes Spring-aware, but in most applications that's not so bad.

Solution 5

You could deploy a custom BeanPostProcessor in your application context to do it. Or if you don't mind implementing a Spring interface in your bean, you could use the InitializingBean interface or the "init-method" directive (same link).

Share:
334,890

Related videos on Youtube

peakit
Author by

peakit

Updated on January 26, 2022

Comments

  • peakit
    peakit over 2 years

    I have a use case where I need to call a (non-static) method in the bean only-once at the ApplicationContext load up. Is it ok, if I use MethodInvokingFactoryBean for this? Or we have a some better solution?

    As a side note, I use ConfigContextLoaderListener to load the Application Context in web application. And want, that if bean 'A' is instantiated just call methodA() once.

    How can this be done nicely?

  • peakit
    peakit almost 15 years
    Does anyone has details on how to write a BeanPostProcessor. That sounds to be exactly what I need. Cheers :)
  • Rob H
    Rob H almost 15 years
    Spring ships with many examples. Just look at the JavaDoc API for BeanPostProcessor and you'll find links to many implementing classes. Then look at the source code for them.
  • Mark
    Mark almost 15 years
    Is there a reason you would choose implementing the interface over specifying an init-method in the XML?
  • Jon Skeet
    Jon Skeet almost 15 years
    Oliver gives me some nice excuses, but really I'd just forgotten about the init-method :) One other reason is that the type itself knows that it needs to be "finished" after all the properties have been set - it isn't fundamentally something which should be in the configuration.
  • khylo
    khylo over 13 years
    Thanks, this works. Note if you want to use with Spring you must include "<context:annotation-config />" to register the CommonAnnotationBeanPostProcessor bean (as mentioned above)
  • Donal Fellows
    Donal Fellows about 13 years
    A suitable <context:component-scan> also works, and can be useful for reducing startup time if you have large non-Spring libraries on your classpath.
  • Donal Fellows
    Donal Fellows about 13 years
    I think it's actually a good thing to use @PostConstruct precisely because it is part of the class that it needs the method calling at the end of initialization processing.
  • Donal Fellows
    Donal Fellows about 13 years
    Technically, @PostConstruct (when used in a Spring-based app) is tied to the lifespan of the owning Spring context. Such contexts can be used in all sorts of applications.
  • Ayorinde
    Ayorinde about 13 years
    That was the behaviour i was expecting but didn't work for me.
  • Jackie
    Jackie about 11 years
    postConstruct should be better in most cases, though, as we dont wanna mess up with spring bean initialization.
  • juckele
    juckele over 10 years
    The JavaDoc for PostConstruct says that only one method can be annotated with it per class:docs.oracle.com/javaee/5/api/javax/annotation/…
  • Yngve Sneen Lindal
    Yngve Sneen Lindal over 9 years
    @lwpro2 What do you mean by "don't wanna mess up with spring bean initialization" here?
  • mjs
    mjs over 9 years
    @PostConstruct doesn't work with a transactional manager, see: forum.spring.io/forum/spring-projects/data/…
  • John Rix
    John Rix over 9 years
    @PostConstruct also won't be of much use to you when the bean you are instantiating is not a class of your own but some third party class
  • KJEjava48
    KJEjava48 over 7 years
    @Mercer Traieste what should i give for the class attribute here? Can i give the controller class here?
  • user482745
    user482745 about 7 years
    If that class REALLY needs it and you cannot do it in constructor, than I consider it to be code smell.
  • demaniak
    demaniak over 6 years
    @PostConstruct is usually very helpful, but in my case I found that the Authentication instance was not available in the the SecurityContext at the time that postConstruct was called by the framework.