Circular Dependency in Spring

This tutorial explains one of the basic mistake done by the spring developers while defining the spring beans. Spring will not allow Circular Dependency and will throw an exception (BeanCurrentlyInCreationException) at the time of loading the configuration files. Also it is not good practice to design your project to have the circular dependency. What is circular dependency?. For example : Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. When you try to inject both the beans to each other. spring’s IOC container detects it as circular dependency. Lets look at the below code snippet.

ObjA.java

package javabeat.net.core.ioc;

public class ObjA {
	private ObjB b;
	public ObjA(ObjB b){
		this.b = b;
	}
}

ObjB.java

package javabeat.net.core.ioc;

public class ObjB {
	private ObjA a;
	public ObjB(ObjA a){
		this.a = a;
	}
}

Spring Beans Configuration

<context:component-scan base-package="javabeat.net.core.ioc"/>
	<bean id="aBean" class="javabeat.net.core.ioc.ObjA">
		<constructor-arg ref="bBean"/>
	</bean>
	<bean id="bBean" class="javabeat.net.core.ioc.ObjB">
		<constructor-arg ref="aBean"/>
	</bean>

SpringContextLoader.java

package javabeat.net.core.ioc;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringContextLoader {
	public static void main (String args[]){
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("javabeat/net/core/ioc/spring-beans-ioc.xml");
		applicationContext.close();
	}
}

When you run the above example, you will get the following exception:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'aBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.
beforeSingletonCreation(DefaultSingletonBeanRegistry.java:327)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.
getSingleton(DefaultSingletonBeanRegistry.java:217)
	at org.springframework.beans.factory.support.AbstractBeanFactory.
doGetBean(AbstractBeanFactory.java:292)
	at org.springframework.beans.factory.support.AbstractBeanFactory.
getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveReference(BeanDefinitionValueResolver.java:323)

Comments

comments

About Krishna Srinivasan

He is Founder and Chief Editor of JavaBeat. He has more than 8+ years of experience on developing Web applications. He writes about Spring, DOJO, JSF, Hibernate and many other emerging technologies in this blog.

Comments

  1. This problem can be tackled using Layered Architecture.
    Put your services in one layer and sub services + supporting low level functions in layers below.
    Follow basic TCP/IP protocol stack rules like
    1. two components in the same layer can not invoke each other’s methods
    2. components in layer-1 can only invoke comps in level-2
    doing this you will reduce probability of cyclic dependencies. As a designer you will just to have to keep a track of top-most layer, there you should not introduce dependency. I hop this helps.

Speak Your Mind

*