Most times when you are injecting a bean into another bean in ColdSpring you will use setter injections. They look like:
<bean id="bean1" class="com.nictunney.Bean1"/> <bean id="bean2" class="com.nictunney.Bean2"> <property name="Bean1"> <ref bean="Bean1"/> </property> </bean>
Bean2 defines a mutator (setter) method, setBean1(). ColdSpring will inject the Bean1 into Bean2 when Bean2 is created by explicitly calling Bean2.setBean1(bean1). This is a best practice when performing dependency injection to prevent circular dependencies.
So the problem we were encountering in code was that the Bean2 constructor was calling a method that relied on the Bean1 property, which was of course undefined during the instantiation. It took a little while to track this down as this was a Model-Glue subapplication with lots of other stuff that could have been creating the error.
So, the lesson learned is to remember how ColdSpring and DI works. ColdSpring is going to create an instance of a bean, call the bean's constructor and then perform any necessary setter injections. It all makes perfect sense, except when you least expect it ;)
The answer in this case was to determine if a circular dependency would occur, which in our case it wouldn't, and instead inject the dependent bean via a constructor argument like this:
<bean id="bean1" class="com.nictunney.Bean1"/> <bean id="bean2" class="com.nictunney.Bean2"> <constructor-arg name="bean1"> <ref bean="Bean1" /> </constructor-arg> </bean>
In the constructor call setBean1(arguments.bean1).
Nice post Nic.ReplyDelete
Quick question though, are advantages/disadvantages over which injection you should use? Ie, Constructor or Setter (property).
Does it depend on personal preference and consistency in the config?
@jbuda - it is summed up nicely here: http://sourceforge.net/apps/trac/coldspring/wiki/MoreAdvanced - let me know if any of it doesn't make sense and I'll do another post on it.ReplyDelete