Spring源码解析之分析各 scope的bean创建(4)

在 Spring 中存在着不同的 scope,默认是 singleton,还有prototype等。下面便分析各个scope。

1.singleton。

if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            destroySingleton(beanName);
            throw ex;
        }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        //获取singletonObjects全局锁
        synchronized (this.singletonObjects) {
            //获取singletonObjects对应的bean实例
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                //创建bean之前的处理,添加singletonsCurrentlyInCreation缓存
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //初始化bean 其实就是调用createBean()
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //后置处理,singletonsCurrentlyInCreation除去缓存
                    afterSingletonCreation(beanName);
                }
                //添加进入对应的缓存中,刷新对应缓存
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

 在isSingleton为true情况下,getSingleton()和createBean()方法。

分析getSingleton,这个方法并不是核心区创建bean的函数,而是对创建前后进行逻辑操作和校验。

  •  获取singletonObjects全局锁,并获取对应的bean实例,如果bean存在直接返回。这样可以确保单例模式只存在唯一的  bean实例
  • 如果不存在,进行beforeSingletonCreation(beanName),singletonsCurrentlyInCreation加入缓存
  • singletonFactory.getObject()调用createBean()创建bean
  • afterSingletonCreation去除singletonsCurrentlyInCreation缓存
  • addSingleton()添加刷新对应的缓存。
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

一个 put、一个 add、两个 remove。singletonObjects 单例 bean 的缓存,singletonFactories 单例 beanFactory 的缓存,earlySingletonObjects “早期”创建的单例 bean 的缓存,registeredSingletons 已经注册的单例缓存。

 

原型模式:

Object prototypeInstance = null;
try {
	beforePrototypeCreation(beanName);
	prototypeInstance = createBean(beanName, mbd, args);
}
finally {
	afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

原型模式的创建也是一样的:

  • 调用 beforeSingletonCreation() 记录加载原型模式 bean 之前的加载状态,即前置处理。
  • 调用 createBean() 创建一个 bean 实例对象。
  • 调用 afterSingletonCreation() 进行加载原型模式 bean 后的后置处理。
  • 调用 getObjectForBeanInstance() 从 bean 实例中获取对象。

其他:

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 {
    Object scopedInstance = scope.get(beanName, () -> {
        beforePrototypeCreation(beanName);
        try {
            return createBean(beanName, mbd, args);
        }
        finally {
            afterPrototypeCreation(beanName);
        }
    });
    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
    throw new BeanCreationException(beanName,
            "Scope '" + scopeName + "' is not active for the current thread; consider " +
            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
            ex);
}

 

三个模块最主要的两个方法createBean()和getObjectForBeanInstance()。createBean()下篇会讲解。getObjectForBeanInstance()是这样解释的(《Spring 源码深度解析》):

这个方法主要是验证以下我们得到的 bean 的正确性,其实就是检测当前 bean 是否是 FactoryBean 类型的 bean,如果是,那么需要调用该 bean 对应的 FactoryBean 实例的 getObject() 作为返回值。无论是从缓存中获得到的 bean 还是通过不同的 scope 策略加载的 bean 都只是最原始的 bean 状态,并不一定就是我们最终想要的 bean。举个例子,加入我们需要对工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义 factory-method 方法中返回的 bean,而 getObjectForBeanInstance() 就是完成这个工作的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章