Aug 29th, 2006, 09:17 AM
depends-on bean def xml working correctly?
I'm not sure if depends-on is broken or if it does just not work the way I think it should.
First... I'm using Spring 1.2.8
Basically, I have written a helper class that implements Spring's lifecycle callback interfaces InitializingBean and ApplicationContextAware. This helper class is responsible for obtaining all the beans in the context that implement a certain interface and then inject all of them into another class that knows nothing about Spring. The class that does not know anything about Spring also has an "init-method" xml attribute in the bean def file. My problem is that I need the init method fired on the Spring aware helper class before the init method on the class that knows nothing of Spring. I thought placing a depends-on attribute on the non Spring bean would take care of this but it does not. Any ideas if depends-on is working as designed or if it is broken? If it is working as designed is there any way I can control the order of firing the init methods?
here is part of my bean def file.
<bean id="ServiceHandlerRegisterHelper" class="com.mycomp.ServiceHandlerRegisterHelper">
<property name="serviceHandlerRegister" ref="ApplicationRegistrationService"/>
<bean id="ApplicationRegistrationService" init-method="init" depends-on="ServiceHandlerRegisterHelper" class="com.mycomp.ApplicationRegistrationServiceIm pl">
<property name="applicationRegistrationDao" ref="ApplicationRegistrationDao"/>
<property name="serviceInfoDao" ref="ServiceInfoDao"/>
<bean id="ApplicationStartSuspensionHandler" class="com.mycomp.ApplicationStartSuspensionHandle r"/>
So here the helper will inject the ApplicationStartSuspensionHandler into the ApplicationRegistrationService bean.
Aug 29th, 2006, 09:26 AM
In that form, your configuration cannot work. You declare that the ApplicationRegistrationService depends on ServiceHandlerRegisterHelper, but you need ApplicationRegistrationService to set up ServiceHandlerRegisterHelper (since it is a property thereof). That is kind of a cycle.
I can not tell you how to resolve this, since I don't know the details, but that is definitely the point to look after.
Aug 29th, 2006, 01:27 PM
I think it should do what you want if you just take the "depends-on" off the ApplicationRegistrationService, if the configuration we can see here is the whole story. The ServiceHandlerRegisterHelper depends on it implicitly through the property ref. Did that not work?
If you want more control over the order in which beans initialise you can sometimes use bean factory hierarchies. Defining the ApplicationRegistrationService in a parent context will guarantee that it can be separately and cleanly initialised before anything in the child context.
Last edited by Dave Syer; Aug 30th, 2006 at 01:16 AM.
Aug 29th, 2006, 04:26 PM
After some poking around I can see how it is a circular dependency issue. I have written many helper classes that work this way but this is the first case where the object I am trying to help has an init-method to fire. It turns out that the way beans are instantiated in the container is not the way I had previously thought. I was under the impression that all singleton beans would have their constructors invoked and then Spring would go back and fill in the dependencies. In actuallity the beans are constructed and the properties are set before Spring moves onto the next bean. I guess I thought it worked that way because I pretty much exclusively use setter injection. It would be pretty hard for Spring to work that way if I were using constructor injection.
What I ended up doing was removing the depends-on and the init-method attributes from the ApplicationRegistrationService bean. I then added an initialize method on the ApplicationRegistrationServiceImpl class (well, one of the interfaces that it implements). This initialize method is called by the ServiceHandlerRegisterHelper bean after it sets properties on the ApplicationRegistrationService bean. I think this solution works pretty well for my situation. My non Spring aware service remains ignorant to Spring and the Spring helper class does all the Spring specific tasks.
If anyone has any ideas that are more elegant please let me know.
Thanks for the help