您所在的位置: > 主页 > 玉溪信息港 > 消费 > 正文
Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析!来源: 日期:2020-11-19 04:57:45  阅读:-

    优质文章,及时送达

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    编辑 | Java之间(gengecn)

    来源 | tech.souyunku.com/?p=13107

    在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近吧整个流程化成了一个流程图。待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程。注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码

    一、获取Bea

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    第一阶段获取Bean

    这里的流程图的入口在 AbstractBeanFactory类的doGetBean方法,这里可以配合前面的 getBean方法分析文章进行阅读。主要流程就是

    1、先处理Bean 的名称,因为如果以“&”开头的Bean名称表示获取的是对应的FactoryBean对象;

    2、从缓存中获取单例Bean,有则进一步判断这个Bean是不是在创建中,如果是的就等待创建完毕,否则直接返回这个Bean对象

    3、如果不存在单例Bean缓存,则先进行循环依赖的解析

    4、解析完毕之后先获取父类BeanFactory,获取到了则调用父类的getBean方法,不存在则先合并然后创建Bean

    二、创建Bean

    2.1 创建Bean之前

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    在真正创建Bean之前逻辑

    这个流程图对应的代码在 AbstractAutowireCapableBeanFactory类的createBean方法中。

    1、这里会先获取RootBeanDefinition对象中的Class对象并确保已经关联了要创建的Bean的Class 。整编:微信公众号,搜云库技术团队,ID:souyunku

    2、这里会检查3个条件

    (1)Bean的属性中的 beforeInstantiationResolved字段是否为true,默认是false。

    (2)Bean是原生的Bean

    (3)Bean的 hasInstantiationAwareBeanPostProcessors属性为true,这个属性在Spring准备刷新容器钱转杯BeanPostProcessors的时候会设置,如果当前Bean实现了InstantiationAwareBeanPostProcessor则这个就会是true。

    当三个条件都存在的时候,就会调用实现的 InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,然后获取返回的Bean,如果返回的Bean不是还会调用实现的BeanPostProcessor接口的postProcessAfterInitialization方法,这里用代码说明

    1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {

    2. Object bean = ;

    3. //条件1

    4. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {

    5. //条件2跟条件3

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

    7. Class targetType = determineTargetType(beanName, mbd);

    8. if (targetType != ) {

    9. //调用实现的postProcessBeforeInstantiation方法

    10. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

    11. if (bean != ) {

    12. //调用实现的postProcessAfterInitialization方法

    13. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

    14. }

    15. }

    16. }

    17. //不满足2或者3的时候就会设置为false

    18. mbd.beforeInstantiationResolved = (bean != );

    19. }

    20. return bean;

    21. }

    1、如果上面3个条件其中一个不满足就不会调用实现的方法。默认这里都不会调用的这些BeanPostProcessors的实现方法。然后继续执行后面的doCreateBean方法。

    2.1 真正的创建Bean,doCreateBean

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    doCreateBean方法逻辑

    这个代码的实现还是在 AbstractAutowireCapableBeanFactory方法中。流程是

    1、先检查instanceWrapper变量是不是,这里一般是,除非当前正在创建的Bean在factoryBeanInstanceCache中存在这个是保存还没创建完成的FactoryBean的集合。

    2、调用createBeanInstance方法实例化Bean,这个方法在后面会讲解

    3、如果当前RootBeanDefinition对象还没有调用过实现了的MergedBeanDefinitionPostProcessor接口的方法,则会进行调用 。整编:微信公众号,搜云库技术团队,ID:souyunku

    4、 当满足以下三点

    (1)是单例Bean

    (2)尝试解析bean之间的循环引用

    (3)bean目前正在创建中

    则会进一步检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口如果实现了则调用是实现的getEarlyBeanReference方法 5、 调用populateBean方法进行属性填充,这里后面会讲解 6、 调用initializeBean方法对Bean进行初始化,这里后面会讲解

    2.1.1 实例化Bean,createBeanInstance

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    实例化Bean

    这里的逻辑稍微有一点复杂,这个流程图已经是简化过后的了。简要根据代码说明一下流程

    1. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @ableObject[] args) {

    2. //步骤1

    3. Class beanClass = resolveBeanClass(mbd, beanName);


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

    5. throw new BeanCreationException(mbd.getResourceDescription, beanName,

    6. "Bean class isn't public, and non-public access not allowed: "+ beanClass.getName);

    7. }

    8. //步骤2

    9. Supplier instanceSupplier = mbd.getInstanceSupplier;

    10. if (instanceSupplier != ) {

    11. return obtainFromSupplier(instanceSupplier, beanName);

    12. }

    13. //步骤3

    14. if (mbd.getFactoryMethodName != ) {

    15. return instantiateUsingFactoryMethod(beanName, mbd, args);

    16. }



    17. boolean resolved = false;

    18. boolean autowireNecessary = false;

    19. if (args == ) {

    20. synchronized (mbd.constructorArgumentLock) {

    21. if (mbd.resolvedConstructorOrFactoryMethod != ) {

    22. resolved = true;

    23. autowireNecessary = mbd.constructorArgumentsResolved;

    24. }

    25. }

    26. }

    27. //步骤4.1

    28. if (resolved) {


    29. if (autowireNecessary) {

    30. return autowireConstructor(beanName, mbd, , );

    31. }

    32. else {


    33. return instantiateBean(beanName, mbd);

    34. }

    35. }


    36. //步骤4.2

    37. Constructor ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

    38. if (ctors != || mbd.getResolvedAutowireMode == AUTOWIRE_CONSTRUCTOR ||

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

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

    41. }


    42. //步骤5

    43. ctors = mbd.getPreferredConstructors;

    44. if (ctors != ) {

    45. return autowireConstructor(beanName, mbd, ctors, );

    46. }



    47. return instantiateBean(beanName, mbd);

    48. }

    1、先检查Class是否已经关联了,并且对应的修饰符是否是public的

    2、如果用户定义了Bean实例化的函数,则调用并返回

    3、如果当前Bean实现了FactoryBean接口则调用对应的FactoryBean接口的getObject方法

    4、根据getBean时候是否传入构造参数进行处理

    4.1如果没有传入构造参数,则检查是否存在已经缓存的无参构造器,有则使用构造器直接创建,没有就会调用instantiateBean方法先获取实例化的策略默认是CglibSubclassingInstantiationStrategy,然后实例化Bean。最后返回

    4.2如果传入了构造参数,则会先检查是否实现了SmartInstantiationAwareBeanPostProcessor接口,如果实现了会调用determineCandidateConstructors获取返回的候选构造器。整编:微信公众号,搜云库技术团队,ID:souyunku

    4.3检查4个条件是否满足一个

    (1)构造器不为,

    (2)从RootBeanDefinition中获取到的关联的注入方式是构造器注入(没有构造参数就是setter注入,有则是构造器注入)

    (3)含有构造参数

    (4)getBean方法传入构造参数不是空

    满足其中一个则会调用返回的候选构造器实例化Bean并返回,如果都不满足,则会根据构造参数选则合适的有参构造器然后实例化Bean并返回

    5、如果上面都没有合适的构造器,则直接使用无参构造器创建并返回Bean。

    2.1.2 填充Bean,populateBean

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    填充Bean

    这里还是根据代码来说一下流程

    1. protected void populateBean(String beanName, RootBeanDefinition mbd, @ableBeanWrapper bw) {

    2. if (bw == ) {

    3. if (mbd.hasPropertyValues) {

    4. throw new BeanCreationException(

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

    6. }

    7. else {

    8. // Skip property population phase for instance.

    9. return;

    10. }

    11. }



    12. boolean continueWithPropertyPopulation = true;

    13. //步骤1

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

    15. for (BeanPostProcessor bp : getBeanPostProcessors) {

    16. if (bp instanceof InstantiationAwareBeanPostProcessor) {

    17. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

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

    19. continueWithPropertyPopulation = false;

    20. break;

    21. }

    22. }

    23. }

    24. }


    25. if (!continueWithPropertyPopulation) {

    26. return;

    27. }

    28. //步骤2--------------------

    29. PropertyValues pvs = (mbd.hasPropertyValues ? mbd.getPropertyValues : );


    30. int resolvedAutowireMode = mbd.getResolvedAutowireMode;

    31. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

    32. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

    33. // Add property values based on autowire by name if applicable.

    34. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

    35. autowireByName(beanName, mbd, bw, newPvs);

    36. }

    37. // Add property values based on autowire by type if applicable.

    38. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

    39. autowireByType(beanName, mbd, bw, newPvs);

    40. }

    41. pvs = newPvs;

    42. }


    43. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors;

    44. boolean needsDepCheck = (mbd.getDependencyCheck != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);


    45. PropertyDescriptor filteredPds = ;

    46. //步骤3

    47. if (hasInstAwareBpps) {

    48. if (pvs == ) {

    49. pvs = mbd.getPropertyValues;

    50. }

    51. for (BeanPostProcessor bp : getBeanPostProcessors) {

    52. if (bp instanceof InstantiationAwareBeanPostProcessor) {

    53. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

    54. PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance, beanName);

    55. if (pvsToUse == ) {

    56. if (filteredPds == ) {

    57. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

    58. }

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

    60. if (pvsToUse == ) {

    61. return;

    62. }

    63. }

    64. pvs = pvsToUse;

    65. }

    66. }

    67. }

    68. if (needsDepCheck) {

    69. if (filteredPds == ) {

    70. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

    71. }

    72. checkDependencies(beanName, mbd, filteredPds, pvs);

    73. }

    74. //步骤4

    75. if (pvs != ) {

    76. applyPropertyValues(beanName, mbd, bw, pvs);

    77. }

    78. }

    1、检查当前Bean是否实现了InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation方法则调用,并结束Bean的填充。

    2、将按照类型跟按照名称注入的Bean分开,如果注入的Bean还没有实例化的这里会实例化,然后放到PropertyValues对象中。

    3、如果实现了InstantiationAwareBeanPostProcessor类的postProcessProperties则调用这个方法并获取返回值,如果返回值是,则有可能是实现了过期的postProcessPropertyValues方法,这里需要进一步调用postProcessPropertyValues方法

    4、进行参数填充

    2.1.3 初始化Bean,initializeBean

    Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

    初始化Bean

    同时这里根据代码跟流程图来说明

    1、如果Bean实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware则调用对应实现的方法 。整编:微信公众号,搜云库技术团队,ID:souyunku

    2、Bean不为并且bean不是合成的,如果实现了BeanPostProcessorpostProcessBeforeInitialization则会调用实现的postProcessBeforeInitialization方法。在ApplicationContextAwareProcessor类中实现了postProcessBeforeInitialization方法。而这个类会在Spring刷新容器准备beanFactory的时候会加进去,这里就会被调用,而调用里面会检查Bean是不是EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware的实现类。这里就会调用对应的实现方法。代码如下

    1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    2. .......

    3. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    4. .......

    1. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

    2. if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||

    3. bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||

    4. bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){

    5. return bean;

    6. }


    7. AccessControlContext acc = ;


    8. if (System.getSecurityManager != ) {

    9. acc = this.applicationContext.getBeanFactory.getAccessControlContext;

    10. }


    11. if (acc != ) {

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

    13. invokeAwareInterfaces(bean);

    14. return ;

    15. }, acc);

    16. }

    17. else {

    18. invokeAwareInterfaces(bean);

    19. }


    20. return bean;

    21. }

    22. 1、实例化Bean然后,检查是否实现了InitializingBeanafterPropertiesSet方法,如果实现了就会调用

      2、Bean不为并且bean不是合成的,如果实现了BeanPostProcessorpostProcessBeforeInitialization则会调用实现的postProcessAfterInitialization方法。

      到此创建Bean 的流程就没了,剩下的就是容器销毁的时候的了

      三、destory方法跟销毁Bean

      欢迎关注公众号:Java后端

      Bean在创建完毕之后会检查用户是否指定了 destroyMethodName以及是否实现了DestructionAwareBeanPostProcessor接口的requiresDestruction方法,如果指定了会记录下来保存在DisposableBeanAdapter对象中并保存在bean的disposableBeans属性中。代码在AbstractBeanFactoryregisterDisposableBeanIfNecessary

      1. protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {

      2. ......

      3. registerDisposableBean(beanName,

      4. new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors, acc));

      5. ......

      6. }

      1. public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,

      2. List postProcessors, @ableAccessControlContext acc) {

      3. .......

      4. String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);

      5. if (destroyMethodName != && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&

      6. !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {

      7. ......

      8. this.destroyMethod = destroyMethod;

      9. }

      10. this.beanPostProcessors = filterPostProcessors(postProcessors, bean);

      11. }

      在销毁Bean的时候最后都会调用 AbstractAutowireCapableBeanFactorydestroyBean方法。

      1. public void destroyBean(Object existingBean) {

      2. new DisposableBeanAdapter(existingBean, getBeanPostProcessors, getAccessControlContext).destroy;

      3. }

      这里是创建一个 DisposableBeanAdapter对象,这个对象实现了Runnable接口,在实现的run方法中会调用实现的DisposableBean接口的destroy方法。并且在创建DisposableBeanAdapter对象的时候会根据传入的bean是否实现了DisposableBean接口来设置invokeDisposableBean变量,这个变量表实有没有实现DisposableBean接口

      1. public DisposableBeanAdapter(Object bean, List postProcessors, AccessControlContext acc) {

      2. Assert.not(bean, "Disposable bean must not be ");

      3. this.bean = bean;

      4. this.beanName = bean.getClass.getName;

      5. //根据传入的bean是否实现了`DisposableBean`接口来设置`invokeDisposableBean`变量

      6. this.invokeDisposableBean = (this.bean instanceof DisposableBean);

      7. this.nonPublicAccessAllowed = true;

      8. this.acc = acc;

      9. this.beanPostProcessors = filterPostProcessors(postProcessors, bean);

      10. }


      11. public void destroy {

      12. ......

      13. //根据invokeDisposableBean决定是否调用destroy方法

      14. if (this.invokeDisposableBean) {

      15. if (logger.isTraceEnabled) {

      16. logger.trace("Invoking destroy on bean with name '"+ this.beanName +"'");

      17. }

      18. try {

      19. if (System.getSecurityManager != ) {

      20. AccessController.doPrivileged((PrivilegedExceptionAction) -> {

      21. ((DisposableBean) this.bean).destroy;

      22. return ;

      23. }, this.acc);

      24. }

      25. else {

      26. ((DisposableBean) this.bean).destroy;

      27. }

      28. }

      29. catch (Throwable ex) {

      30. String msg = "Invocation of destroy method failed on bean with name '"+ this.beanName +"'";

      31. if (logger.isDebugEnabled) {

      32. logger.warn(msg, ex);

      33. }

      34. else {

      35. logger.warn(msg + ": "+ ex);

      36. }

      37. }

      38. }

      39. ......

      40. }

      41. 四、总结。

        最后来一个大的流程

        Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

        实例化前的准备阶段

        Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

        实例化前

        Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

        实例化后

        Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

        初始化前

        Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

        -END-

        (正文已结束)

        免责声明及提醒:此文内容为本网所转载企业宣传资讯,该相关信息仅为宣传及传递更多信息之目的,不代表本网站观点,文章真实性请浏览者慎重核实!任何投资加盟均有风险,提醒广大民众投资需谨慎!