BeanFactory处理bean生命周期全流程

    BeanFactory的默认实现为DefaultListableBeanFactory,其中Bean生命周期与方法映射如下,建议参考源码一起看。

一、BeanDefinition注册阶段-registerBeanDefinition

这个阶段分为两个部分:首先通过 beanName 注册 BeanDefinition ,然后再注册别名 alias

通过 beanName 注册

处理过程如下:

1、首先 BeanDefinition 进行校验,该校验也是注册过程中的最后一次校验了,主要是对 AbstractBeanDefinition 的 methodOverrides 属性进行校验

2、根据 beanName 从缓存中获取 BeanDefinition,如果缓存中存在,则根据 allowBeanDefinitionOverriding 标志来判断是否允许覆盖,如果允许则直接覆盖,否则抛出 BeanDefinitionStoreException 异常

3、若缓存中没有指定 beanName 的 BeanDefinition,则判断当前阶段是否已经开始了 Bean 的创建阶段,如果是,则需要对 beanDefinitionMap 进行加锁控制并发问题,否则直接设置即可。

4、若缓存中存在该 beanName 或者单例 bean 集合中存在该 beanName,则调用 resetBeanDefinition() 重置 BeanDefinition 缓存。

其实整段代码的核心就在于 this.beanDefinitionMap.put(beanName, beanDefinition);

BeanDefinition 的缓存也不是神奇的东西,就是定义 map ,key 为 beanName,value 为 BeanDefinition

注册 alias

BeanDefinitionRegistry.registerAlias 完成 alias 的注册,注册 alias 和注册 BeanDefinition 的过程差不多。在最好调用了 checkForAliasCircle() 来对别名进行了检测

 

二、BeanDefinition合并阶段-getMergedBeanDefinition

流程如下:

1、找到父BeanDefinition,如果没有找到就直接将自身当作父BeanDefinition,找到的话就看看父BeanDefinition有没有父BeanDefinition,并且通过getMergedBeanDefinition方法得到父BeanDefinition合并之后的BeanDefinition。

2、合并BeanDefinition,通过父BeanDefinition创建出一个RootBeanDefinition对象,然后子BeanDefinition覆盖父BeanDefinition创建出来的对象(覆盖属性之类的)。

3、将合并后的BeanDefinition放入一个mergedBeanDefinitions集合中,最后将合并后的BeanDefinition返回。

在其中我们需要注意其中几个地方:

  1. 合并后的BeanDefinition是用RootBeanDefinition接收的,这也是为什么RootBeanDefinition到现在的版本依然还在使用,因为它还应用在合并BeanDefinition的操作中。
  2. 需要注意不论有没有父BeanDefinition都会发生合并的操作,而且父BeanDefinition的合并可能在这其中执行。

 

三、Bean实例化前阶段-resolveBeforeInstantiation

这个阶段是一个不常用的操作,在这个阶段我们可以生成一个代理类来替换我们生成实例。底层是通过InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法。

 

四、Bean实例化阶段-createBeanInstance

创建bean的实例,负责创建的方法为createBeanInstance,具体代码如下:        

 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

                   // 解析class

                   Class beanClass = resolveBeanClass(mbd, beanName);

                   //确保class不为空,并且访问权限为public

                   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

                   }

                   //配置的一种特殊的callback回调方法,通过这个callback创建bean

                   Supplier instanceSupplier = mbd.getInstanceSupplier();

                   if (instanceSupplier != null) {

                            return obtainFromSupplier(instanceSupplier, beanName);

                   }

                   //通过工厂方法创建

                   if (mbd.getFactoryMethodName() != null)  {

                            return instantiateUsingFactoryMethod(beanName, mbd, args);

                   }

                  

                   // 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器

                   // 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析

                   boolean resolved = false;

                   boolean autowireNecessary = false;

                   if (args == null) {

                            synchronized (mbd.constructorArgumentLock) {

                                     if (mbd.resolvedConstructorOrFactoryMethod != null) {

                                               //已经解析过class的构造器

                                               resolved = true;

                                               autowireNecessary = mbd.constructorArgumentsResolved;

                                     }

                            }

                   }

                   if (resolved) {

                            //已经解析过class的构造器,使用已经解析好的构造器

                            if (autowireNecessary) {

                                     //构造函数自动注入

                                     return autowireConstructor(beanName, mbd, null, null);

                            }

                            else {

                                     //使用默认构造器

                                     return instantiateBean(beanName, mbd);

                            }

                   }



                   // 需要根据参数解析、确定构造函数

                   Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

                   // 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空

                   if (ctors != null ||

                                     mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

                                     mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {

                            //构造函数自动注入

                            return autowireConstructor(beanName, mbd, ctors, args);

                   }



                   // 使用默认构造器

                   return instantiateBean(beanName, mbd);

         }

五、Bean实例化后阶段-populateBean

在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,以及属性赋值。在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。源码解析如下:

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {

    // pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝

    // 在本例中,里面存在一个propertyValueList,里面只有一个propertyValue:key->value="student"->RuntimeBeanReference("")

         PropertyValues pvs = mbd.getPropertyValues();



         if (bw == null) {

                   if (!pvs.isEmpty()) {

                            throw new BeanCreationException(

                                               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

                   }

                   else {

                            // 空对象直接返回

                            return;

                   }

         }



         // 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值

         // 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回

         boolean continueWithPropertyPopulation = true;



         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

                   for (BeanPostProcessor bp : getBeanPostProcessors()) {

                            if (bp instanceof InstantiationAwareBeanPostProcessor) {

                                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

                                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

                                               continueWithPropertyPopulation = false;

                                               break;

                                     }

                            }

                   }

         }



         if (!continueWithPropertyPopulation) {

                   return;

         }



    // 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置

    // 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置

         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||

                            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

                   // 深拷贝当前已有的配置

                   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);



                   // 根据名称进行注入

                   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {

                            autowireByName(beanName, mbd, bw, newPvs);

                   }



                   // // 根据类型进行注入

                   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

                            autowireByType(beanName, mbd, bw, newPvs);

                   }

        // 结合注入后的配置,覆盖当前配置

                   pvs = newPvs;

         }

   

    // 容器是否注册了InstantiationAwareBeanPostProcessor

         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

         // 是否进行依赖检查

         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

   

         if (hasInstAwareBpps || needsDepCheck) {

             // 过滤出所有需要进行依赖检查的属性编辑器

                   PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

                   if (hasInstAwareBpps) {

                            for (BeanPostProcessor bp : getBeanPostProcessors()) {

                                // 如果有相关的后置处理器,进行后置处理

                                     if (bp instanceof InstantiationAwareBeanPostProcessor) {

                                               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

                                               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

                                               if (pvs == null) {

                                                        return;

                                               }

                                     }

                            }

                   }

                   if (needsDepCheck) {

                       // 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化

                            checkDependencies(beanName, mbd, filteredPds, pvs);

                   }

         }

    // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例

         applyPropertyValues(beanName, mbd, bw, pvs);

}

 

六、Bean初始化阶段-initializeBean

当BeanFactory将bean创建成功,并设置完成所有它们的属性后,需要进行初始化,通过initializeBean方法进行初始化,源码如下:        

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

                   if (System.getSecurityManager() != null) {

                            AccessController.doPrivileged((PrivilegedAction) () -> {

                                     invokeAwareMethods(beanName, bean);

                                     return null;

                            }, getAccessControlContext());

                   }

                   else {

                            invokeAwareMethods(beanName, bean);

                   }



                   Object wrappedBean = bean;

                   if (mbd == null || !mbd.isSynthetic()) {

                            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

                   }



                   try {

                            invokeInitMethods(beanName, wrappedBean, mbd);

                   }

                   catch (Throwable ex) {

                            throw new BeanCreationException(

                                               (mbd != null ? mbd.getResourceDescription() : null),

                                               beanName, "Invocation of init method failed", ex);

                   }

                   if (mbd == null || !mbd.isSynthetic()) {

                            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

                   }



                   return wrappedBean;

         } 
  

整个初始化流程如下:

1、调用各类感知Aware接口

2、执行applyBeanPostProcessorsBeforeInitialization初始化前的 处置操作

3、调用InitializingBean接口初始化

4、如果配置了method-init,则调用其方法初始化

5、调用applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作

 

七、Bean销毁阶段-destroyBean

1.率先销毁所有依赖于这个单例bean的所有bean,道理很简单,如果当前单例bean被销毁了,而依赖于当前单例bean的bean对象调用单例bean时必然会出现空指针异常

2.真正开始执行单例bean的destroy()方法来销毁bean

3.containedBeanMap销毁这个单例bean中包含的其他bean对象(即引入的依赖,但是实际上这个map好像并没有用到,而且引用的bean也不应该立即销毁,因为可能有其他bean同时也在引用,或许应该检查到没有引用的时候再销毁,但是spring中好像并没有这么做)

4.从依赖bean缓存列表dependentBeanMap中(键值对,如service->controller list)删除所有相关被依赖项

5.删除依赖列表dependenciesForBeanMap(键值对,如controller -> service list)

源码如下:

protected void destroyBean(String beanName, @Nullable DisposableBean bean) {

                   // Trigger destruction of dependent beans first...

                   Set dependencies;

                   synchronized (this.dependentBeanMap) {

                            // Within full synchronization in order to guarantee a disconnected Set

                            dependencies = this.dependentBeanMap.remove(beanName);

                   }

                   if (dependencies != null) {

                            if (logger.isTraceEnabled()) {

                                     logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);

                            }

                            for (String dependentBeanName : dependencies) {

                                     destroySingleton(dependentBeanName);

                            }

                   }



                   // Actually destroy the bean now...

                   if (bean != null) {

                            try {

                                     bean.destroy();

                            }

                            catch (Throwable ex) {

                                     if (logger.isWarnEnabled()) {

                                               logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);

                                     }

                            }

                   }



                   // Trigger destruction of contained beans...

                   Set containedBeans;

                   synchronized (this.containedBeanMap) {

                            // Within full synchronization in order to guarantee a disconnected Set

                            containedBeans = this.containedBeanMap.remove(beanName);

                   }

                   if (containedBeans != null) {

                            for (String containedBeanName : containedBeans) {

                                     destroySingleton(containedBeanName);

                            }

                   }



                   // Remove destroyed bean from other beans' dependencies.

                   synchronized (this.dependentBeanMap) {

                            for (Iterator>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {

                                     Map.Entry> entry = it.next();

                                     Set dependenciesToClean = entry.getValue();

                                     dependenciesToClean.remove(beanName);

                                     if (dependenciesToClean.isEmpty()) {

                                               it.remove();

                                     }

                            }

                   }



                   // Remove destroyed bean's prepared dependency information.

                   this.dependenciesForBeanMap.remove(beanName);

         }

 

你可能感兴趣的:(java,学习,IOC)