如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();
}
}