I'm interested to know if there is an interface that I can use to tell Spring to start a particular bean up, invoke its initialization procedure (either as an InitializingBean via afterPropertiesSet(), or via an init-method, or some other way), and then throw it away.
My use case is a simple "sanity-checker" that will check the database for valid values upon startup for a web application. Although the overhead would be small for our particular bean, keeping that bean for all eternity in the application context is pointless, as once the bean had initialized, it is no longer needed.
I'm sure there are other use cases for this type of behavior, but I haven't found anything like this yet in Spring.
In particular, I'm looking for it in the Java variant of Spring, I have access to 3.x and up as needed.
EDIT: based on the accepted answer, the following is a simple hack to provide the solution:
public final class NullReturningBeanPostProcessor implements BeanPostProcessor {
private List<String> beanNamesToDiscard = new ArrayList<String>();
/**
* Creates a new {@link NullReturningBeanPostProcessor} instance.
*/
public NullReturningBeanPostProcessor() {
super();
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanNamesToDiscard.contains(beanName)) {
return null;
}
return bean;
}
public void setBeanNamesToDiscard(List<String> beanNamesToDiscard) {
if (beanNamesToDiscard != null) {
this.beanNamesToDiscard = beanNamesToDiscard;
}
}
}
Placing this bean post processor with the appropriate beans to discard in the application context will make them null, and eligible for garbage collection after they've been initialized. The bean configuration metadata, unfortunately, will still remain in the application context.
Hello Friends, If you Want to call the method after your bean is initialize in spring you can use the following options. Use the afterProprtiesSet method. 2:- You can use the annotation @PostConstruct in your class. to enable this you need to define in your application context xml file.
Use init-method attribute.
In spring you can initialize a bean by having the applicationContext. xml invoke a constructor, or you can set properties on the bean.
Bean life cycle is managed by the spring container. When we run the program then, first of all, the spring container gets started. After that, the container creates the instance of a bean as per the request, and then dependencies are injected. And finally, the bean is destroyed when the spring container is closed.
To achieve this, I would make that bean implement BeanPostProcessor
and then:
@Override
Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean == this ? null : bean;
}
This should cause the ApplicationContext to discard it but only after it has performed the initialization steps.
Note that you also need to implement postProcessBeforeInitialization()
and there just write return bean;
.
Update: this does NOT work. But not due to MetroidFan2002's comment (see bellow), but due to another part of the JavaDoc:
ApplicationContexts can autodetect BeanPostProcessor beans in their bean definitions and apply them to any beans subsequently created.
So obviously you cannot apply a BeanPostProcessor to itself. Sorry for the false alarm :)
You could use a MethodInvokingFactoryBean
bean definition to execute a method on application context initialization. Though, you do have to be careful with dependencies if some beans need to be initialized before the method is invoked. The following would execute the checkDatabase
method on the bean named sanityChecker
after beanA
, beanB
and beanC
are initialized:
<bean
id="methodInvoker"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="beanA, beanB, beanC"
lazy-init="false"
p:singleton="false"
p:target-method="checkDatabase"
p:target-object-ref="sanityChecker"
/>
<bean
id="sanityChecker"
class="com.example.SanityChecker"
lazy-init="true"
scope="prototype"
/>
Since checkDatabase
is a prototype, its lifecycle is not managed by the application context and should be garbage collected after initialization; that's something a unit test could prove out. methodInvoker
might also need to be a prototype for checkDatabase
to be garbage collected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With