admin 管理员组

文章数量: 888526

单例Bean的创建流程

简要介绍

bean的创建,需要经过查找,创建,注入,实例化三阶段

finishBeanFactoryInitialization

前言提到,refresh方法执行了finishBeanFactoryInitialization,这个方法便是完成了bean的创建与初始化。
每一个非lazy的单例bean,都会根据长长的调用链,最终进入doGetBean方法

doGetBean

doGetBean是用于返回bean的方法,如果bean不存在,还会调用其内部的doCreateBean完成bean的创建
注意这里的markBeanAsCreated(beanName);它做到了beanName的不重复,也保证了单例bean的安全。

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 从缓存池中获取Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {//如果存在,判断一下是否还在创建,都已经创建但是状态却是还在创建当然是错的。然后判断一下if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}//这是为了防止beanFactory套用beanFactory,这里提供了递归使用getObject方法,从而获取最终beanbean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 空的,要不是没创建过的单例bean,要不是原型bean,并且这个bean一定不能是if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 打上已经创建的标记,防止对象反复创建if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 优先完成@DependOn注解指定的类的bean的创建与获取String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 这里面实际上就是增加这个bean依赖了哪个bean,和哪个被依赖的bean被这个bean依赖的双重引用registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// 如果是单例if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// 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;}});// 也是递归向里调用,直到返回的不是factoryBeanbean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}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);}else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}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 ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// 检查一下是否需要格式转换,比如XML的字符串转化为对象的类型if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {logger.trace("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;
}

试图直接返回

这是singletonObject的逻辑,如果一级有,直接返回,如果一级没有,那么就可能涉及修改操作,所以提前完成上锁。为什么锁的是一级缓存而不是二级缓存呢,正是因为三级缓存在完成调用之后会将对象加入二级缓存,然后其它有着相同需求正在等待的线程就可以直接从二级缓存取出对象,而不需要双重检验机制了。
然后进行二级和三级缓存的查找。如果是在三级缓存中找到的,那么就会调用其中getObject方法,这个方法在单例中就是getReference方法

//三级缓存,保存工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//二级缓存,保存工厂创建的对象
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//一级缓存,保存所有完成创建的对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}

doCreateBean方法的“AOP”

以下对源码的验证部分进行大量删除,只剩下主干
这个方法在调用doCreateBean之前,会将其加入一个set表示正在创建,在调用doCreateBean正常结束之后会将其删除,并完成一级缓存的添加和二三级缓存的清除

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 添加进入singletonsCurrentlyInCreation,表示是正在创建的单例对象beforeSingletonCreation(beanName);boolean newSingleton = false;try {//这里才是真正调用了 doCreateBeansingletonObject = singletonFactory.getObject();// 如果走到这里说明初始化成功了newSingleton = true;} finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 从singletonsCurrentlyInCreation中移除afterSingletonCreation(beanName);}// 如果初始化成功了,那么加入一级缓存if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}
}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);}
}

doCreateBean的实体

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// 实例化beanif (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// 可以理解为走了一个beanPostProcessorssynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);mbd.postProcessed = true;}}// 如果设置了属性,并且是正在创建的单例bean,就会添加单例工厂.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;// 注入属性populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject = initializeBean(beanName, exposedObject, mbd);// 如果支持循环引用,并且存在该对象,这是为了保证返回的一定是代理对象if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}}}// 如果需要回调destory方法,会放入destroybeans,这样在销毁的时候就会从destroybeans剔除并回调registerDisposableBeanIfNecessary(beanName, bean, mbd);return exposedObject;
}

关联的属性这时候注入

属性注入的时候对Autowire注解进行了注入

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}// 使用AutowiredAnnotationBeanPostProcessor,将类中所有Autowired注解都提取出来,并在postProcessPropertyValues逐一完成注入for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}// 把property数组放入beanWrapper里面,便于后续使用if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}

对于三级缓存的解释

比如A包含B,B包含A的关系,用户尝试获取A。
一开始进入A的getBean,由于缓存中不存在A,所以进入A的create方法,会生成单例工厂,并将单例工厂放入三级缓存,然后进入属性注入环节,会尝试注入B,这时陷入B的getBean。
B会标记自己是正在生成,然后进入create方法,生成单例工厂,并将单例工厂放入三级缓存,然后进入属性注入环节,会尝试注入A,这时陷入A的getBean,这时会从三级缓存中取出A的单例工厂,并且调用其getEarlyReference方法,AbstractAutoProxyCreator会将A加入AOP缓存,然后生成代理对象,并将A移出三级缓存,将其注入二级缓存,然后返回给B使用。B获取到之后会继续完成属性注入和初始化代理,然后从三级缓存中删除自己,加入一级缓存,返回代理对象B给A。
A拿到了B的代理对象,会继续完成属性注入和初始化代理,在初始化代理时候,A会检查AOP缓存,由于A会在AOP缓存里发现自己,所以直接返回。在create方法的最后,A会从二级缓存中取出A的代理,然后从二级缓存中删除A,并加入一级缓存,将A的代理返回给用户。

如何理解三级缓存的作用呢?我认为就是设计分层。如果你想要少缓存的话,你甚至可以只有一层,你在实例化完bean之后,直接完成AOP,那么后期注入所有人获取到的都是AOP完的,那就无所谓三级缓存了。
因为Spring选择将AOP作为一种beanPostProcessor的功能,在此之前就完成了属性注入,所以我们需要第三层的存在,这样注入的时候就可以直接获得暴露的工厂。而第二层的设计就是为了告诉你,这一层就是没有完成好初始化的bean。对于后期的getBean而言,除非特殊情况(懒加载),否则它就会直接从一层返回,从而达到了底层循环依赖透明的效果。

本文标签: 单例Bean的创建流程