使用lookup-method解决singleton bean依赖prototype bean的问题
在Spring里面,当一个singleton bean依赖一个prototype bean,那么,因为singleton bean是单例的,因此prototype bean在singleton bean里面也会变成单例,例如:
public class Main{
private Man man;
//这里注入一个prototype的Man实例
public void setMan(Man man) { this.man= man; }
public Man getMan() { return man; }
}
配置文件:
<bean id="man" class="test.American" scope="prototype"/> <!-- 这里声明一个多例的bean -->
<bean id="main" class="test.Main"> <!-- 这里声明一个单例的bean --> <property name="man" ref="man"/> <!-- 这里依赖一个多例的bean --> </bean>
如果我为Main创建一个单例bean,那么当我注入Man实例的时候,man属性也会变成单例了,跟我预期的效果不一样。
解决方法1:放弃依赖注入,使用传统工厂思想,通过ApplicationContext的getBean方法获取Man的实例。但是缺点比较明显,跟Spring框架耦合了。
解决方法2:如果我仍然想得到依赖注入带来的好处,那么可以使用Spring提供的lookup-method来注入。
不过使用之前,我们需要下载多一个jar包,叫做cglib-full.jar,我使用的版本是cglib-full-2.0.1.jar。
现在我们只需要修改一下我们的配置文件就可以了,现在修改成:
<bean id="man" class="test.American" scope="prototype"/> <!-- 这里声明一个多例的bean -->
<bean id="main" class="test.Main"> <!-- 这里声明一个单例的bean --> <lookup-method name="getMan" bean="man"/> <!-- 这里依赖一个多例的bean --> </bean>
注意红色字体部分,我们不使用原来的property标签,改用looup-method标签。name属性表示当调用指定方法的时候重新注入一个实例,这个实例对应bean属性的值。
最后,请看如下测试代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Main main = (Main) ctx.getBean("main");
Man man1 = main.getMan(); //这里通过Spring的注入,获取第1个Man实例
Man man2 = main.getMan(); //这里通过Spring的注入,获取第2个Man实例
super.assertFalse(man1 == man2);
//请注意,man1和man2现在已经指向两个不同的引用,因此它们的引用不相等。
posted on 2013-11-08 14:32 heartstage 阅读(483) 评论(0) 编辑 收藏 举报