|
|||||
|
|||||
About Mutual Dependency
It may not always be possible to avoid components that are dependent on each other. Such mutual dependency is carefully handled by Yan and Nuts. Typically, there are two ways to go about dealing with mutual dependency: singleton and proxy. singletonIt is perfectly legal to allow two singleton components depend on each other, as long as such dependency is not essential to create the component instance itself. For example, the bean properties can depend on each other freely. Corresponding to the following java code: A a = new A(); B b = new B(); a.setB(b); b.setA(a); Two singleton beans work just fine: <bean id="a" class="A" singleton="true"> <prop key="b" val="$b"/> </bean> <bean id="b" class="B" singleton="true"> <prop key="a" val="$a"/> </bean> It will be a problem if the two beans are not singleton, the following code will fail with cyclic dependency exception: <bean id="a" class="A" singleton="false"> <prop key="b" val="$b"/> </bean> <bean id="b" class="B" singleton="false"> <prop key="a" val="$a"/> </bean> When it is required that the beans cannot be singleton, the <sequence> tag can be used to mimic the Java code that first calls the constructors of the two classes and then set the bean properties: <sequence id="result"> <ctor var="a" class="A"/> <ctor var="b" class="B"/> <setter component="$a" name="b" val="$b"/> <setter component="$b" name="a" val="$a"/> <return val="$a"/> </sequence> proxyBeans can depend on each other because the properties can be set after all the instances needed are constructed. public class A{ public A(B b){...} } public class B{ public B(A a){...} } new A(new B(new A(...))); There's an infinite loop anyway. However, if the design can be changed to more conform the "programming-against-interface" idiom, a lazy evaluated proxy can be to rescue. For example, we re-design the class A and B by introducing two interfaces IA and IB: public interface IA{...} public class A implements IA{ public A(IB b){...} } public class B implements IB{ public B(IA a){...} } class A and B do not depend on each other directly any more. They depend on the IA and IB interfaces. Then, we can use the <proxy> tag to get around the problem: <value val="$a"> <local> <proxy id="ia" type="tests.jfun.models.IA" component="$a"/> <proxy id="ib" type="tests.jfun.models.IB" component="$b"/> <ctor id="a" class="tests.jfun.models.A"> <arg ind="0" val="$ib"/> </ctor> <ctor id="b" class="tests.jfun.models.B"> <arg ind="0" val="$ia"/> </ctor> </local> </value> The lazy evaluated proxy breaks the dependency cycle and gives us an object graph that we want. Created by benyu |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||