vlambda博客
学习文章列表

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


点击右侧关注,了解黑客的世界!

点击右侧关注,掌握进阶之路!



点击右侧关注,探讨技术话题!


作者丨撸码识途
链接:
https://www.jianshu.com/p/70b935f2b3fe

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

一、获取Bean

第一阶段获取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 。
2、这里会检查3个条件
(1)Bean的属性中的 beforeInstantiationResolved 字段是否为true,默认是false。
(2)Bean是原生的Bean
(3)Bean的 hasInstantiationAwareBeanPostProcessors 属性为true,这个属性在Spring准备刷新容器钱转杯BeanPostProcessors的时候会设置,如果当前Bean实现了 InstantiationAwareBeanPostProcessor 则这个就会是true。
当三个条件都存在的时候,就会调用实现的 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法,然后获取返回的Bean,如果返回的Bean不是null还会调用实现的 BeanPostProcessor 接口的 postProcessAfterInitialization 方法,这里用代码说明
 
   
   
 

  1. protectedObject resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {



  2. Object bean = null;



  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 != null) {



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



  10. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);



  11. if(bean != null) {



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



  13. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);



  14. }



  15. }



  16. }



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



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



  19. }



  20. return bean;



  21. }


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

2.1 真正的创建Bean,doCreateBean

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

doCreateBean方法逻辑

这个代码的实现还是在 AbstractAutowireCapableBeanFactory 方法中。 流程是
1、先检查 instanceWrapper 变量是不是null,这里一般是null,除非当前正在创建的Bean在 factoryBeanInstanceCache 中存在这个是保存还没创建完成的FactoryBean的集合。
2、调用createBeanInstance方法实例化Bean,这个方法在后面会讲解
3、如果当前 RootBeanDefinition 对象还没有调用过实现了的 MergedBeanDefinitionPostProcessor 接口的方法,则会进行调用 。
4、 当满足以下三点
(1)是单例Bean
(2)尝试解析bean之间的循环引用
(3)bean目前正在创建中
则会进一步检查是否实现了 SmartInstantiationAwareBeanPostProcessor 接口如果实现了则调用是实现的 getEarlyBeanReference 方法5、 调用 populateBean 方法进行属性填充,这里后面会讲解6、 调用 initializeBean 方法对Bean进行初始化,这里后面会讲解

2.1.1 实例化Bean,createBeanInstance

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

实例化Bean

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

  1. protectedBeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @NullableObject[] args) {



  2. //步骤1



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




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



  5. thrownewBeanCreationException(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 != null) {



  11. return obtainFromSupplier(instanceSupplier, beanName);



  12. }



  13. //步骤3



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



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



  16. }





  17. boolean resolved = false;



  18. boolean autowireNecessary = false;



  19. if(args == null) {



  20. synchronized(mbd.constructorArgumentLock) {



  21. if(mbd.resolvedConstructorOrFactoryMethod != null) {



  22. resolved = true;



  23. autowireNecessary = mbd.constructorArgumentsResolved;



  24. }



  25. }



  26. }



  27. //步骤4.1



  28. if(resolved) {




  29. if(autowireNecessary) {



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



  31. }



  32. else{




  33. return instantiateBean(beanName, mbd);



  34. }



  35. }




  36. //步骤4.2



  37. Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);



  38. if(ctors != null|| 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 != null) {



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



  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 获取返回的候选构造器。
4.3 检查4个条件是否满足一个
(1)构造器不为null,
(2)从RootBeanDefinition中获取到的关联的注入方式是构造器注入(没有构造参数就是setter注入,有则是构造器注入)
(3)含有构造参数
(4)getBean方法传入构造参数不是空
满足其中一个则会调用返回的候选构造器实例化Bean并返回,如果都不满足,则会根据构造参数选则合适的有参构造器然后实例化Bean并返回
5、如果上面都没有合适的构造器,则直接使用无参构造器创建并返回Bean。

2.1.2 填充Bean,populateBean

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

填充Bean

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

  1. protectedvoid populateBean(String beanName, RootBeanDefinition mbd, @NullableBeanWrapper bw) {



  2. if(bw == null) {



  3. if(mbd.hasPropertyValues()) {



  4. thrownewBeanCreationException(



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



  6. }



  7. else{



  8. // Skip property population phase for null instance.



  9. return;



  10. }



  11. }





  12. boolean continueWithPropertyPopulation = true;



  13. //步骤1



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



  15. for(BeanPostProcessor bp : getBeanPostProcessors()) {



  16. if(bp instanceofInstantiationAwareBeanPostProcessor) {



  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() : null);




  30. int resolvedAutowireMode = mbd.getResolvedAutowireMode();



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



  32. MutablePropertyValues newPvs = newMutablePropertyValues(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 = null;



  46. //步骤3



  47. if(hasInstAwareBpps) {



  48. if(pvs == null) {



  49. pvs = mbd.getPropertyValues();



  50. }



  51. for(BeanPostProcessor bp : getBeanPostProcessors()) {



  52. if(bp instanceofInstantiationAwareBeanPostProcessor) {



  53. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;



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



  55. if(pvsToUse == null) {



  56. if(filteredPds == null) {



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



  58. }



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



  60. if(pvsToUse == null) {



  61. return;



  62. }



  63. }



  64. pvs = pvsToUse;



  65. }



  66. }



  67. }



  68. if(needsDepCheck) {



  69. if(filteredPds == null) {



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



  71. }



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



  73. }



  74. //步骤4



  75. if(pvs != null) {



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



  77. }



  78. }


1、检查当前Bean是否实现了 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation 方法则调用,并结束Bean的填充。
2、将按照类型跟按照名称注入的Bean分开,如果注入的Bean还没有实例化的这里会实例化,然后放到 PropertyValues 对象中。
3、如果实现了 InstantiationAwareBeanPostProcessor 类的 postProcessProperties 则调用这个方法并获取返回值,如果返回值是null,则有可能是实现了过期的 postProcessPropertyValues 方法,这里需要进一步调用 postProcessPropertyValues 方法
4、进行参数填充

2.1.3 初始化Bean,initializeBean

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

初始化Bean

同时这里根据代码跟流程图来说明
1、如果Bean实现了 BeanNameAware , BeanClassLoaderAware , BeanFactoryAware 则调用对应实现的方法 。
2、Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor 的 postProcessBeforeInitialization 则会调用实现的 postProcessBeforeInitialization 方法。 在 ApplicationContextAwareProcessor 类中实现了 postProcessBeforeInitialization 方法。 而这个类会在Spring刷新容器准备 beanFactory 的时候会加进去,这里就会被调用,而调用里面会检查Bean是不是 EnvironmentAware , EmbeddedValueResolverAware , ResourceLoaderAware , ApplicationEventPublisherAware , MessageSourceAware , ApplicationContextAware 的实现类。 这里就会调用对应的实现方法。 代码如下
 
   
   
 

  1. protectedvoid prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {



  2. .......



  3. beanFactory.addBeanPostProcessor(newApplicationContextAwareProcessor(this));



  4. .......


 
   
   
 

  1. publicObject postProcessBeforeInitialization(Object bean, String beanName) throwsBeansException{



  2. if(!(bean instanceofEnvironmentAware|| bean instanceofEmbeddedValueResolverAware||



  3. bean instanceofResourceLoaderAware|| bean instanceofApplicationEventPublisherAware||



  4. bean instanceofMessageSourceAware|| bean instanceofApplicationContextAware)){



  5. return bean;



  6. }




  7. AccessControlContext acc = null;




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



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



  10. }




  11. if(acc != null) {



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



  13. invokeAwareInterfaces(bean);



  14. returnnull;



  15. }, acc);



  16. }



  17. else{



  18. invokeAwareInterfaces(bean);



  19. }




  20. return bean;



  21. }


1、实例化Bean然后,检查是否实现了 InitializingBean 的 afterPropertiesSet 方法,如果实现了就会调用
2、Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor 的 postProcessBeforeInitialization 则会调用实现的 postProcessAfterInitialization 方法。
到此创建Bean 的流程就没了,剩下的就是容器销毁的时候的了

三、destory方法跟销毁Bean

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

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



  2. ......



  3. registerDisposableBean(beanName,



  4. newDisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));



  5. ......



  6. }


 
   
   
 

  1. publicDisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,



  2. List<BeanPostProcessor> postProcessors, @NullableAccessControlContext acc) {



  3. .......



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



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



  6. !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {



  7. ......



  8. this.destroyMethod = destroyMethod;



  9. }



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



  11. }


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

  1. publicvoid destroyBean(Object existingBean) {



  2. newDisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();



  3. }


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

  1. publicDisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {



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



  3. this.bean = bean;



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



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



  6. this.invokeDisposableBean = (this.bean instanceofDisposableBean);



  7. this.nonPublicAccessAllowed = true;



  8. this.acc = acc;



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



  10. }




  11. publicvoid 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() != null) {



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



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



  22. returnnull;



  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. }


四、总结。

最后来一个大的流程

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

实例化前的准备阶段

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

实例化前

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

实例化后

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

初始化前

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

 推荐↓↓↓ 

长

按

关

注

👉【】都在这里!


涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。

万水千山总是情,点个 “ 在看” 行不行