Demo
如下所示 ,通过将ServiceImplScope 设置为原型,但是在每次调用接口获取的时候 返回的都是同一个实例。显然是不符合我们预期。
@RequestMapping(path = "/hiScope",method = RequestMethod.GET)
public String hiScope() {
return "hiScope"+serviceImplScope;
}
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ServiceImplScope {
}
hiScopecom.qxlx.spingboot.service.ServiceImplScope@5d805805
分析问题
对于一个bean来说 分为三个步骤,加载、创建、使用。那么一定在创建bean、填充属性的时候被固定了。
解决方案
方式一:通过IOC容器 每次都获取
@RequestMapping(path = "/hiScope",method = RequestMethod.GET)
public String hiScope() {
return "hisocpe"+getServiceImplScope();
}
public ServiceImplScope getServiceImplScope () {
return applicationContext.getBean(ServiceImplScope.class);
}
具体原理
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 如果是单例 第一次会创建 第二次会直接从缓冲中获取
// Create bean instance.
if (mbd.isSingleton()) {
// xxx
} else if (mbd.isPrototype()) {
// 原型 就会创建一个新的实例
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
return (T) bean;
}
方式二: @Lookup注解
@RequestMapping(path = "/hiScope",method = RequestMethod.GET)
public String hiScope() {
return "hi"+getServiceImplScopePrototype();
}
@Lookup
public ServiceImplScope getServiceImplScopePrototype() {
return null;
}
使用方法注入的方法需要满足以下语法要求:
<public|protected> [abstract] theMethodName(no-arguments);
方法访问权限必须为public或protected:这与@Lookup的底层原理有关——动态代理
abstract(可选):如果是抽象方法,代理类会实现这方法;如果不是抽象方法,代理类会覆盖这方法
return-type:原型Bean的类型
no-arguments:参数列表必须为空
那么具体原理是什么呢?
Spring bean作用域
① singleton
使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。
② prototype
使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
③ request
该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。
④ session
该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。
⑤ global-session
该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。
标签:02,return,Spring,bean,50,Bean,实例,hiScope,public From: https://blog.csdn.net/jia970426/article/details/143463286