How to call a method after bean initialization is complete?
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 injavax.*
) - 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).
Related videos on Youtube
peakit
Updated on January 26, 2022Comments
-
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 almost 15 yearsDoes anyone has details on how to write a BeanPostProcessor. That sounds to be exactly what I need. Cheers :)
-
Rob H almost 15 yearsSpring 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 almost 15 yearsIs there a reason you would choose implementing the interface over specifying an init-method in the XML?
-
Jon Skeet almost 15 yearsOliver 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 over 13 yearsThanks, 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 about 13 yearsA 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 about 13 yearsI 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 about 13 yearsTechnically,
@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 about 13 yearsThat was the behaviour i was expecting but didn't work for me.
-
Jackie about 11 yearspostConstruct should be better in most cases, though, as we dont wanna mess up with spring bean initialization.
-
juckele over 10 yearsThe 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 over 9 years@lwpro2 What do you mean by "don't wanna mess up with spring bean initialization" here?
-
mjs over 9 years@PostConstruct doesn't work with a transactional manager, see: forum.spring.io/forum/spring-projects/data/…
-
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 over 7 years@Mercer Traieste what should i give for the class attribute here? Can i give the controller class here?
-
user482745 about 7 yearsIf that class REALLY needs it and you cannot do it in constructor, than I consider it to be code smell.
-
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.