在面试中经常会被问到一个问题,就是SpringBean的生命周期,用大白话说就是在创造到销毁按顺序调用了什么方法@mikechen
对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收,而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制。
Spring中每个Bean的生命周期如下,主要分为以下8大步骤:
下面针对图上的SpringBean声明周期的8大步骤一一详解。
1.实例化Bean
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。,容器通过获取BeanDefinition对象中的信息进行实例化。
并且这一步仅仅是简单的实例化,并未进行依赖注入,实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性。
2.设置对象属性(依赖注入)
实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入。
3.处理Aware接口
接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:
①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanld)方法,此处传递的就是Spring配置文件中Bean的id值;
②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean已经实现了ApplicationContextAware接口,会调用setpplicationcontex(ApplicationContext)方法,传入Spring上下文;
4.BeanPostProcessor
当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。
该接口提供了两个函数:
- postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行,因此称为前置处理。 所有Aware接口的注入就是在这一步完成的。
- postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行,因此称为后置处理。
5.InitializingBean 与init-method
如果Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。
6.如果这个Bean实现了BeanPostProcessor接口,将会调用
postProcessAfterlnitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
7.DisposableBean
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
8.destroy-method
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
SpringBean生命周期总结
主要分为8大步骤:
1、实例化Bean对象;
2、设置Bean属性;
3、如果通过各种Aware接口声明了依赖关系,则会注入Bean对容器基础设施层面的依赖
Aware接口集体包括BeanNameAware、BeanFactoryAware和ApplicationContextAware
分别注入Bean ID、Bean Factory 和ApplicationContext
4、如果实现了BeanPostProcesser,调用BeanPostProcesser的前置初始化方法postProcessBeforeInitialization;
5、如果实现了InitializingBean接口,则会调用afterPropertiesSet方法;
6、调用Bean自身定义的init方法;
7、调用BeanPostProcesser的后置方法postProcessAfterInitialization;
8、容器关闭前调用DisposableBean的destroy方法和自身的destroy方法。
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》