Hi everyone,
i have a problem with initialization of beans, that depends on each other using depends-on. You can find it strange to have such dependencies or implementation in provided example below, but my case is quite complex, so i tried to simplify it, for example by shorten long circular dependencies. As a result, the problem was reproduced with two beans. So, what is the case... i have two bean definitions:
and the java classes:Code:<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="beanB" class="com.il.spring.test.model.BeanB" scope="singleton" depends-on="beanA" init-method="init"> </bean> <bean id="beanA" class="com.il.spring.test.model.BeanA" scope="singleton"> <property name="staticGate" ref="beanA" /> <property name="beanB" ref="beanB" /> </bean> </beans>
This leads to the following exception in BeanB init method:Code:public class BeanA { private static BeanA staticGate; private BeanB beanB; public void setStaticGate(BeanA staticGate) { BeanA.staticGate = staticGate; } public static BeanA getStaticGate() { return staticGate; } public void setBeanB(BeanB beanB) { this.beanB = beanB; } public void test() { } public class BeanB { public void init() { try { BeanA.getStaticGate().test(); } catch (Exception e) { e.printStackTrace(); } }
It's looks like the BeanA is not fully ready to use, when the BeanB init method is called, regardless of the configuration, where it is said that beanB depends-on beanA.Code:java.lang.NullPointerException at com.il.spring.test.model.BeanB.init(BeanB.java:10) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1544) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1485) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
I made some further test and reworked the configuration and class BeanB to:
and everything worked. So it seems like when defining a dependency using property ref, beanA is ready to use, when the beanB init method is called. And this is the strange thing - it works with property ref, but do not work with "depends-on". Can you please give me an explanation why this happens? Again, you can find it strange why i am not using directly beanA, as it is said to be property of beanB. This is simple example of complex usage of this beanA in my application, where this service can be accessible only by this "staticGate".Code:<bean id="beanB" class="com.il.spring.test.model.BeanB" scope="singleton" init-method="init"> <property name="beanA" ref="beanA" /> </bean> <bean id="beanA" class="com.il.spring.test.model.BeanA" scope="singleton"> <property name="staticGate" ref="beanA" /> <property name="beanB" ref="beanB" /> </bean> public class BeanB { private BeanA beanA; public void setBeanA(BeanA beanA) { this.beanA = beanA; } public void init() { try { BeanA.getStaticGate().test(); } catch (Exception e) { e.printStackTrace(); } } }
Thanks in advance


Reply With Quote