Announcement Announcement Module
Collapse
No announcement yet.
Circular Dependencies Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Circular Dependencies

    Hi

    I created a simple test application with surprising results. The application has just two very simple classes. They both reference each other. One gets the references with a constructor argument, the other with a property.

    Interesting enough, this first spring context xml works:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean id="two" class="Two">
        <property name="one"><ref local="one"/></property>
      </bean>
      <bean id="one" class="One">
        <constructor-arg><ref local="two"/></constructor-arg>
      </bean>
    </beans>
    Just reversing the bean definitions results in a total different situation:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean id="one" class="One">
        <constructor-arg><ref local="two"/></constructor-arg>
      </bean>
      <bean id="two" class="Two">
        <property name="one"><ref local="one"/></property>
      </bean>
    </beans>
    The following exception is thrown.

    Code:
    Nov 21, 2005 1:37:15 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [one,two]; root of BeanFactory hierarchy]
    Nov 21, 2005 1:37:15 PM org.springframework.beans.factory.support.AbstractBeanFactory destroySingletons
    INFO: Destroying singletons in factory {org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [one,two]; root of BeanFactory hierarchy}
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'one' defined in class path resource [context.xml]: Can't resolve reference to bean 'two' while setting property 'constructor argument'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'two' defined in class path resource [context.xml]: Can't resolve reference to bean 'one' while setting property 'one'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'one': Requested bean is currently in creation (circular reference when autowiring constructor?)
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'two' defined in class path resource [context.xml]: Can't resolve reference to bean 'one' while setting property 'one'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'one': Requested bean is currently in creation (circular reference when autowiring constructor?)
    org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'one': Requested bean is currently in creation (circular reference when autowiring constructor?)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:186)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:176)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:105)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1012)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:823)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:345)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:176)
    	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:105)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveConstructorArguments(AbstractAutowireCapableBeanFactory.java:713)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:611)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:329)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:275)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:318)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:81)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:66)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:57)
    	at Test.main(Test.java:7)
    So first of all, the order of bean definitions is in fact significant. Second, Spring fails to construct the object graph in this simple case. Note, I was using the following simple test program:

    Code:
    public class Test {
      public static void main(String[] args) {
        BeanFactory factory = new ClassPathXmlApplicationContext("context.xml");
        Two two = (Two) factory.getBean("two");
        System.out.println(two);
        System.out.println(two.getOne());
      }
    }
    Just for fun, I tried to use a BeanFactory:

    Code:
    public class Test {
      public static void main(String[] args) {
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("context.xml"));
        Two two = (Two) factory.getBean("two");
        System.out.println(two);
        System.out.println(two.getOne());
      }
    }
    And guess what, it worked flawlessly in both cases. Hmm. Strange, strange, strange...

    I'm using spring version 1.2.6, and the described behavior is also present in 1.2.5.

  • #2
    Maybe you should report this to Jira (if no according problem is already reported).

    Regards,
    Andreas

    Comment


    • #3
      I've created an issue in Jira: SPR-1487.

      Comment

      Working...
      X