一、bean的作用域
众所周知Spring bean的作用范围取值有五种(scope属性控制):
singleton:单例,也是默认值
prototype: 多例,比如让Spring接管struts2的action的时候就必须配置此属性
request: 一次请求以及此次请求的转发
session: 作用范围是一次会话
globalsession: 作用范围是一次全局绘画,比如多台服务器之间需要共用同一个bean的时候就需要此属性。
二、单例的bean引用原型模式的bean
SingletonA 的代码如下
@Service
public class SingletonA {
@Autowired
private PrototypeB prototypeB;
public void printlnB(){
System.out.println(prototypeB);
}
}
PrototypeB代码如下
@Service
@Scope(value = "prototype")
public class PrototypeB {
}
测试类
public class SpringTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
applicationContext.getBean(SingletonA.class).printlnB();
applicationContext.getBean(SingletonA.class).printlnB();
applicationContext.getBean(SingletonA.class).printlnB();
}
}
结果:
com.arvin.learn.spring.PrototypeB@5204062d
com.arvin.learn.spring.PrototypeB@5204062d
com.arvin.learn.spring.PrototypeB@5204062d
这是应该很容易理解,因为SingletonA是单例的,在整个Spring容器里面只会创建一次,在创建的时候给的prototypeB是什么就是什么了。那么问题来了,假如在某些场景下,SingletonA中用到prototypeB的时候,都是要新的,而不是都是同一个。
方法一:在SingletonA注入ApplicationContext,具体实现如下
@Service
public class SingletonA {
@Autowired
private PrototypeB prototypeB;
@Autowired
private ApplicationContext applicationContext;
public void printlnB(){
prototypeB = applicationContext.getBean(PrototypeB.class);
System.out.println(prototypeB);
}
}
方法二:SingletonA实现ApplicationContextAware接口
@Service
public class SingletonA implements ApplicationContextAware {
@Autowired
private PrototypeB prototypeB;
private ApplicationContext applicationContext;
public void printlnB(){
prototypeB = applicationContext.getBean(PrototypeB.class);
System.out.println(prototypeB);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext =applicationContext;
}
}
方法三:使用Lookup注解
@Service
public class SingletonA {
@Lookup
protected PrototypeB createPrototypeB(){
return null;
};
public void printlnB(){
PrototypeB prototypeB = createPrototypeB();
System.out.println(prototypeB);
}
}
官网上面也有详细的讲解 1.4.6 Lookup Method Injection,地址如下
本文探讨了Spring中bean的作用域,特别是单例bean引用原型bean的情况。当SingletonA需要每次获取PrototypeB的新实例时,提出了三种解决方法:通过注入ApplicationContext、实现ApplicationContextAware接口以及使用Lookup注解。Spring官方文档对此有详细说明。
9749

被折叠的 条评论
为什么被折叠?



