views:

5260

answers:

5

Hi,

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?

+4  A: 

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.

Jon Skeet
Is there a reason you would choose implementing the interface over specifying an init-method in the XML?
Mark
Thats a matter of taste. The interface is part of the Spring component model and serves that and only that purpose while for a custom named method it might not really be obvious that it has to be called to complete component lifecycle. So this serves communication mainly. Of course with the drawback of the introduced dependency to the Spring framework. A nice way in between is the usage of @PostConstruct, as it has clear semantics but does not introduce the dependency...
Oliver Gierke
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.
Jon Skeet
+1  A: 

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).

Rob H
Does anyone has details on how to write a BeanPostProcessor. That sounds to be exactly what I need.Cheers :)
peakit
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.
Rob H
+8  A: 

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.

Mercer Traieste
+1  A: 

Three different approaches to consider as described in the reference

(1) Use init-method attribute.

Pros - does not require bean to implement an interface.

(2) Implement InitializingBean.

Cons - more invasive than the init-method approach.

(3) Use JSR-250 @PostConstruct lifecyle annotation.

Pros:

Useful when using component scanning to autodetect beans.

Makes it clear that a specific method is to be used for initialisation

Cons:

Initialisation no longer centrally specified in configuration. Now scattered throughout code.

toolkit
+1  A: 

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
  • Your class can have as many @PostConstruct and @PreDestroy-annotated methods as you like.
  • 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).
skaffman