Spring 单例模式bean 中引用原型模式bean的一些考虑
程序员文章站
2022-06-03 18:59:56
...
一、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();
}
}
结果:
[email protected]
[email protected]
[email protected]
这是应该很容易理解,因为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,地址如下
上一篇: 有关于葡萄的资料与其功效
下一篇: zuul-封装灰度发布,动态路由