如singleton作用域Bean依赖prototype作用域的Bean,当Spring容器初始化时,他会初始化容器中所有的 singleton Bean ,此时prototype Bean 被创建出来,并注入到singleton Bean中————此处当singleton Bean 被创建后,它就持有一个prototype Bean,容器不再为singleton Bean 执行注入了、
由于singleton Bean具有单例行为,当客户端多次请求singleton Bean 时,Spring 返回给客户端的是同一个实例,这不存在任何问题。问题是:如果客户端多次请求singleton Bean 并调用prototype Bean 的方法时,始终都是调用同一个prototype Bean实例,这就违反了prototype Bean 的初衷了。
解决方法;
1.部分放弃依赖注入:这种方法不太好
2.利用方法注入: 利用lookup方法注入可以让Spring 容器重写容器的Bean 的抽象或具象方法。
public abstract class Chinese implements Person { public Chinese() { System.out.println("Spring实例化主调bean:Chinese实例..."); } //定义一个抽象方法,该方法将由Spring负责实现 public abstract Axe getAxe(); public void useAxe() { System.out.println("正在使用 " + getAxe() + "砍柴!"); System.out.println(getAxe().chop()); } }
<?xml version="1.0" encoding="GBK"?> <!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 定义一个steelAxe实例,指定prototype的作用域 --> <bean id="steelAxe" class="org.crazyit.app.service.impl.SteelAxe" scope="prototype"/> <bean id="chinese" class="org.crazyit.app.service.impl.Chinese"> <!-- 指定getAxe方法返回steelAxe 每次调用getAxe方法将获取新的steelAxe对象 --> <lookup-method name="getAxe" bean="steelAxe"/> </bean> </beans>主程序:
public class BeanTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); Person p = ctx.getBean("chinese" , Person.class); //两次通过p对象使用Axe对象 p.useAxe(); p.useAxe(); } }
原文:http://blog.csdn.net/fangchao3652/article/details/23962625