Spring中Bean的生命周期
作为java开发程序员在面试的时候通常都会被问到Spring完整的生命周期,但是大多数的开发者都回答的不够完整,其实在BeanFactory这个类中Spring源码的作者已经很好的告诉我们了Spring中Bean完整的生命周期了,下图是英文源码注释。完整生命周期总结在文章最后。
(图片如果太小看不清,微信点击图片会自动放大图片就能看清了,下面所有图片可以采用同样的操作,都是自己原创,涂了腾讯的标签,要不然图片无法上传)
为什么要掌握Bean的生命周期呢?因为如果我们了解了它的生命周期,在Bean生成的过程中,我们介入它的周期然后赋给这个Bean一些特性方便我们开发,先介绍一些它的小的用途,然后再去讲解它的整个的生命周期中比较重要的点。
第一个小用途:实现InitializingBean。在Bean里面为static 修饰的静态成员变量赋值,(我们知道如果直接用@Auowired注解是不能直接为static修饰的成员变量赋值的)。
上面 ucClinet 变量不能用@Autowired注解,即使代码中使用了这个注解也是无法给这个变量赋值的,具体为什么后面有讲解。PS:applicationContent这个变量是可以注入的,这个是Spring内部的类,初始化的比较早。
具体为什么能这样做,了解了Bean的生命周期就知道了。
下面通过上面的代码我们就讲解一下Bean生命周期的一些比较重要的过程。 AbstractAutowireCapableBeanFactory这个类的doCreateBean方法开始真正创建Bean。
下图也是doCreateBean中的部分方法。
applyMergedBeanDefinationPostProcessor方法内部包含下图中的方法,依赖注入不支持static修饰的属性。
doCreateBean中的populateBean(beanName, mbd, instanceWrapper)这个方法就是真正开始根据Sping的特性IOC和DI为Bean的属性赋值的,由于前面讲到无法为static修饰的变量进行依赖注入。所以就需要这个后面的initializeBean(beanName, exposedObject, mbd)这个方法了,这个方法在为属性赋值后面才开始执行,如下图:
上图中initializeBean这个方法会执行((InitializingBean) bean).afterPropertiesSet()这个方法,这样在Bean初始化的时候就会完成了static修饰的变量的赋值。提供一个小小思路,这个地方用途很大,看过spring整合mybatis的源码的可以知道很多地方都用到这个初始化的钩子,如下SqlSessionFactoryBean.afterPropertiesSet()也是对它的巧妙应用。
第二个小用途:实现BeanPostProcessor接口在Bean初始化前和后,如果开发中对应的Bean有什么特殊功能可以在如下代码里面实现:
至于这2段代码为什么能在Bean初始化前后分别执行,可以参考Bean初始化的源码如下:
上面2个例在子在开发还是会用到的,特别是第一个开发中灵活使用能极大的提高开发的效率。
Spring中Bean完整生命周期
1:设置beanName 。
2:设置BeanClassLoader。
3:设置BeanFactory 。
4:设置Environment。
5:设置EmbeddedValueResolver。
上面5个步骤在开发中不常介入
6:设置ResourceLoader 。
7:设置ApplicationEventPublisher。
8:设置MessageSource 。
9:设置ApplicationContext。
10:设置ServletContext 。
(6-10要通常需要实现对应的Aware接口,特别是第9个步骤开发中常常用到)
11:执行postProcessBeforeInitialization。
12:执行InitializingBean's afterPropertiesSet。
13:执行custom init-method definition(加了@PostConstruct注解的方法会执行由上面顺序可知这个方法在afterPropertiesSet后执行)。
14:执行postProcessAfterInitialization。
(11-14这几个步骤很重要需要掌握)
15:当Spring容器关闭的时候开始执行DisposableBean's destroy方法销毁Bean。
备注:文中也是使用了IOC和DI这个Spring中的专业名词,由于这个知识点简单所以稍微一笔带过一下(IOC : Inverse of Control 反转控制的概念,就是将原本在程序中手动创建 对象的控制权,交由Spring框架管理。DI : Dependency Injection依赖注入,在Spring框架负责Bean对象时,手动将依赖的对象注入到Bean组件。IOC和DI的区别:IOC控制反转,指将对象的创建权,反转到Spring容器 。DI依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入。)
微信公众号搜索:程序员xiaozhang 。如果遇到Spring的问题也可以私信我 能帮忙解决的尽量解决
微信扫一扫
关注该公众号