Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
Usage of custom scopes breaks functioning of circular references [SPR-5955] #10623
The following construct brings up a BeanCurrentlyInCreationException.
<bean name="A" class="foo.bar.X" scope="session"> <property name="refToB" ref="B"/> </bean> <bean name="B" class="foo.bar.Y" scope="session"> <property name="refToA" ref="a"/> </bean>
As the example shows clearly, there are no problematic references via constructor-arg involved and the same construct but with scope="singleton" does actually work. I see no reason why circular references should not be possible for beans that have a custom scope. Therefor this seems clearly a bug.
Affects: 3.0 M3
1 votes, 3 watchers
Juergen Hoeller commented
I'm afraid I have to disagree: By design, Spring supports circular references for singleton beans only. That's simply a known limitation.
We deliberately chose to not support circular references for scoped beans when we introduced them back in Spring 2.0. Personally, if I got to choose again, I would stick with this decision and not even support circular references for singletons beans either. Circular references introduce more problems that they solve, even for singletons. Some party always gets a not-quite-fully initialized reference there. Anyway, let's leave the well-known circular reference discussion aside and focus on potential solutions...
The underlying reason for the limitation with scoped beans is the Scope SPI. The get operation accepts an ObjectFactory and provides atomicity guarantees, i.e. it never returns a half-initialized object. The scope backend may even build those objects on remote servers or the like, returning a serialized form of it, or it may return a proxy to a cluster-wide shared object. (Custom scopes are used for those kinds of things as well, e.g. with Terracotta as a backend.) In such a scoping scenario, circular dependencies are a no-go to begin with.
So what can we do about it? We could define a new optional operation for Scope implementations, exposing a reference while the object is still being initialized. That's not quite trivial in the details for several reasons (such as doing it on demand only, as well as dealing with clustering side effects of premature HttpSession.setAttribute calls) but doable in principle, at least for request and session scope. We're going to revisit this for Spring 3.1, next to conversation management which happens to be a related topic anyway.
Dirk Scheffler commented
Thank you for your fast reply and the respect you pay to the issue.
Actually my sample was kept simple to show the effect. In my project I use an own custom scope but the the effect is the same. So I would really appreciate to have a way to support circular references and also would do extra effort in my custom scope implementation for it. I think there are scopes where it does not make sense to support circular references and there are scopes where it isn't even possible - so it depends on the implementation. This would be great for me.
Dirk Scheffler commented
I like to ask again if this could be done for spring 3.1.
It would be very nice if it would be possible to support circular references for all custom scope. It is no problem iI this would mean some extra effort for the custom scope implementor. I have own custom scopes (beside session, request) that I want to work with circular references.
Probably we can also think together about what can be done to deal with the problem of the imcompleteness of some circular referenced bean. Are you interested in such a communication? But this would be just for the future. For now we should accept this problem, because in GUI environments the circular references come in by adding event handlers that will on react after the system has been built up completely.
What do you think?
Dirk Scheffler commented
A preliminary solution for the problem
I was able to develop a preliminary solution that works for me and like to share it with the others that think circular references are a natural phenomenon and cannot be left out only because it brings technical problems. This solutions enables circular references for beans of any scope type. Normally circular references are only supported for beans of the normal singleton scope. Please be aware that you will not get fully initialized beans if you use circular references.
Of course my solution could have problems and I would like to know if you find anything.
The solution consists of two parts:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <bean class="org.springframework.beans.factory.config.EarlyReferenceFixBeanPostProcessor"/> </beans>