概述
Spring当中有着不同的bean scope
* singleton :默认值,单例的.
* prototype :多例的.
* request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
* session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
* global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么 globalSession 相当于 session.
在Bean的创建过程中,对不同scope的创建流程是不同的。
//8.bean实例化
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//这里才开始正式创建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//显式从单例池中删除Bean实例
//因为单例模式下为了解决循环依赖,可能它已经存在了.....
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
//和上面一样进行FactoryBean的处理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//原型模式下创建bean,其实这里很简单就是new一个Bean就行了
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//1.加载前置处理
//这个函数主要是处理prototypesCurrentlyInCreation这个ThreadLocal(之前讲过的)
beforePrototypeCreation(beanName);
//2.创建bean对象
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//3.加载后处理
//同样也是操作prototypesCurrentlyInCreation,是上面的反操作
afterPrototypeCreation(beanName);
}
//4.同样处理FactoryBean
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//其他情况下获取bean
else {
//获取scopename指定的Scope对象
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//从指定的scope下创建bean
Object scopedInstance = scope.get(beanName, () -> {
//加载前置处理
beforePrototypeCreation(beanName);
try {
//创建Bean对象
return createBean(beanName, mbd, args);
}
finally {
//加载后置处理
afterPrototypeCreation(beanName);
}
});