Spring Bean的生命周期
一、概述
简单来说,Spring Bean的生命周期只有四个阶段:实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction
Spring Bean的生命周期如下图:
Spring 是什么?
轻量级的开源框架,是一个容器,用来放javaBean(java对象),是一个中间层框架(提供了各种主流框架的整合)起到连接的作用,让企业级开发更加便捷
- 通过IOC达到松耦合目的
- 提供AOP,解耦业务需求和系统需求开发
- 包含并管理了bean的配置和生命周期(容器)
- 将简单的组件配置,组合成复杂的应用(框架)
对AOP的理解?
当需要为分散的对象引入公共行为的时候,例如日志功能(OOP允许定义从上到下的关系,但不适合定义从左到右的关系),日志代码一般都是水平的散布在所有对象中,它与所散布到的对象核心业务功能没有关系。
在OOP的设计中,它导致了大量的代码重复,不利于各个模块的复用,而且对修改不友好,每次都要全部修改。
AOP:将程序中的交叉业务逻辑比如日志、事务,封装成一个切面,然后注入到目标对象中,AOP可以对某个对象的功能进行增强。
二、具体的生命周期
- 实例化Bean
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
对于ApplicationContext容器,当容器启动结束后,
-
通过解析获取BeanDefinition对象中的信息;
-
确定构造方法,进行实例化得到对象(如果有多个构造方法,则要推断构造方法)
-
依次实例化所有的bean
-
依赖注入(设置对象属性)
实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成属性设置与依赖注入。
- 回调Aware接口方法
如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字。
如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。
- BeanPostProcessor前置处理(初始化前方法)
如果想对Bean进行一些自定义的前置处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
- InitializingBean
如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。
- init-method
如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
- BeanPostProcessor后置处理(初始化后方法)
如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法。
由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存缓存技术(如果是单例bean,会缓存起来),在这里会进行AOP;
- 以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
- DisposableBean
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
- Destroy-method
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。