As your Spring applications start to grow and become more complex you?re likely at some stage in your development process to come across a situation where two (or more) beans reference one another. When one bean references another in a Spring application the primary technique for handling this is to use Spring?s Dependency Injection (DI) functionality to inject a reference from the one bean into another. This is probably the most common use of the Inversion of Control (IoC) container and is a simple process to utilise and maintain. However, complications arise when you attempt to inject two beans into one another simultaneously i.e. inject Bean1 into Bean2 and Bean2 into Bean1. An attempt to do this will often result in a circular dependency error resulting in something like:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘beanName’
defined in class path resource []:
Cannot resolve reference to bean ‘beanName’ while setting
bean property ‘beanName’; nested exception is
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name ‘beanName’:
Bean with name ‘beanName’ has been injected into other beans
[beanName2] in its raw version as part of a circular reference,
but has eventually been wrapped
(for example as part of auto-proxy creation).
This means that said other beans do not use the final
version of the bean.

Why is this caused?

From my experience this exception has affected me whilst using Spring’s TransactionProxyFactoryBean to configure (typically) service beans. The error, as far as I understand it, is caused because Spring is trying to effectively inject two semi-initialised proxy beans into one another. What I would like to do in this post is suggest 3 possible techniques for dealing with this problem.

1. Refactor your code

This is probably the simplest and quickest way to fix this problem. Look at your code, analyse why your two beans are referencing one another. Is it absolutely necessary, can you re-write your code in such a way that only one bean need reference the other and vice-versa? Maybe consider creating a third bean that both other beans can be injected into which will perform the functionality that requires the different dependencies. If you have a growing number of circular dependency problems this may actually be indicative of deeper problems and point to overly-complex code, why not use this as an opportunity to step back, refactor your design and simplify your structure?

Although refactoring can be the easiest way to fix this issue, it isn’t always the right answer. Maybe there’s no way you can easily remove the dependencies between the two beans and no sensible or pragmatic way you can create a third bean to fill this function. If this is the case then there are a couple of other ways you can work around this issue.

2. Extend ApplicationContextAware in your Bean(s)

Step 2 is to make use of (or more specifically implement) Spring’s ApplicationContextAware interface in one of the beans causing your circular dependency problem. Implementing this interface will force you to provide a setter in your class for a Spring ApplicationContext. One of the neat things with this though, is that Spring will detect that your bean has implemented ApplicationContextAware and automatically inject a reference to the ApplicationContext into your bean without you having to manually configure injection of the property in your xml bean definition.

Once you have setup your bean (say Bean1) as above, the next task is to stop injecting a reference to Bean2 into it. You can keep the setter method for Bean2 in Bean1 - we’ll make use of this in a minute - we just need to remove the reference to Bean2 from Bean1’s bean definition and thus remove the circular dependency problem.

The last thing to do now is figure out how we’re going to get a reference to Bean2 from Bean1 because currently the Bean2 property in Bean1 is going to be null at application start-up. The way to do this is to look up Bean2 from the ApplicationContext programmatically at run-time. So using our current example, if Bean1 had a method that needed to call a function in Bean2 we could do something like:

public class Bean1 implements ApplicationContextAware
{
ApplicationContext applicationContext;

Bean2 bean2;

public void doSomething()
{
if(bean2 == null)
{
this.setBean2((Bean2)this.applciationContext.getBean("bean2"));
}
bean2.callAnotherMethod();
}

public void setApplicationContext(ApplicationContext applicationContext)
{
this.applicationContext = applicationContext;
}

public void setBean2(Bean2 bean2)
{
bean2 = bean2;
}
}

Of course this is a simplified rendition and we’d probably want to add a load more error handling etc but hopefully it should illustrate this technique. Clearly it’s not the most elegant solution, but it is one that works and providing your code is well tested shouldn’t cause many problems. Where it starts to fall over however, is when you want to use references to Bean2 in more than one place in Bean1, or worse still if you have a number of beans that have circular reference problems. The above technique would still work in this situation, but you’d quickly find your code ballooning up in size and becoming very difficult to manage. So to counter this I offer a third possible solution to this problem, using a BeanPostProcessor.

3. Use a BeanPostProcessor

The third strategy I describe here is actually one that I found first in a post on the Spring forum. This is essentially to create a bean that extends Spring’s BeanPostProcessor interface and use this to initialise any of the properties in beans that cannot be initialised using IoC due to circular dependancy problems. Rather than blog about (and attempt to claim any credit for) this in any great detail I shall instead just point you to the post on the Spring forum where I first encountered someone using technique.

Summary

I think the most elegant solution to this problem is where possible to refactor your code and remove any circular dependencies between your beans. Clearly however, this isn’t always possible and depending on the scenario either looking up one member of a circular dependency directly from the ApplicationContext or alternatively making use of the BeanPostProcessor technique should help to alleviate this problem. Either way, I hope this post has suggested some alternative methods that may be of use to you.