天天看点

【一文读懂】Spring Bean生命周期详解

Spring Bean的生命周期

1 容器初始化

BeanFactory容器初始化:包含容器创建,资源定位,载入,注册。

ApplicationContext容器初始化:包含容器创建,资源定位,载入,注册,Bean生命周期管理等。

1.1 容器初始化流程:
【一文读懂】Spring Bean生命周期详解

2 Bean的生命周期

针对ApplicationContext类型容器,在完成Bean资源加载和注册之后,即进入Bean的生命周期,包含实例化、初始化以及增强,回调等。增强及回调方法如下所示:

2.1 Aware接口

Spring Bean与容器是解耦的,Bean无法感知容器的信息。

Aware是一个具有标识作用的接口,实现该接口的Bean具有被Spring容器通知的能力,本质是通过回调(即在启动时扫描Aware的实现类并实现容器信息注入)。该接口主要在Spring内部框架使用。

2.1.1 为什么使用Aware

Spring Bean与容器是解耦的,Bean无法感知容器的信息。

传统方式是无法获取Bean在容器中的名称的,实现了BeanNameAware的Bean,可以在Bean中重写setBeanName()方法,在IOC初始化时,容器会调用该实现Aware的Bean的setBeanName()方法,从而可以得到容器中Bean的名称。

所以BeanNameAware接口是为了让自身Bean能够感知到,获取到自身在Spring容器中的id属性。

2.1.2 常用的Aware
  • BeanNameAware 获取容器中Bean的名称
  • BeanFactoryAware 获取当前BeanFactory,从而调用容器的服务
  • ApplicationContextAware 获取当前ApplicationContext,从而调用容器的服务
  • ApplicationEventPublisherAware 用于事件的发布
  • ResourceLoaderAware 获取资源加载器,可以获取外部资源文件

2.2 BeanFactoryPostProcessor接口

BeanFactoryPostProcessor是针对于Bean容器的。是在BeanDefinition加载后,Bean实例化之前。操作对象是bean definitions
2.2.1 beanDefinition和适配器模式

关于BeanDefinition的使用模式,官网将其称呼为configuration metadata,直译过来叫“配置元数据”。 他的作用有点类似于Context分层应用的效果(见Spring核心——上下文与IoC 关于 ApplicationContext的说明),目的就是将Bean的配置和初始化工作分成2个互不干扰的部分。

我们知道 Spring现在支持各种各样的方式来添加Bean,比如在XML配置文件中使用标签、使用@Component以及他的派生类注解、可以在@Configuration类中生成、甚至还可以通过RMI实现远程配置等等。如果所有的这些配置来源直接和IoC容器产生关系生成Bean,那么耦合度、代码复杂度会越来越高,而且以后指不定什么时候又会加入什么新的配置方式。

为了解决这个问题Spring的大神们引入了适配器模式——IoC容器只接受BeanDefinition接口,IoC如何初始化一个Bean是仅仅是看BeanDefinition里的信息。而各种配置方式都有自己的适配器,所有的适配器都会根据他所需要处理的内容来生成一个BeanDefinition的实现类。这样,如果新增一个新的配置方式,增加一个适配器就可以搞定。

2.2.2 为什么使用BeanFactoryPostProcessor

定制和修改容器的BeanDefinitions信息。

2.2.3 常用的BeanFactoryPostProcessor接口

PropertyResourceConfigurer :典型实现 属性替换的功能

CustomEditorConfigurer :典型实现 添加自定义属性编辑器的功能

ConfigurationClassPostProcessor:启动@Configuration的扫描功能

2.3 BeanPostProcessor接口

BeanPostProcessor是针对于Bean的。是在Bean实例化后,初始化之前。操作对象是bean instance
2.3.1 为什么使用

Spring容器通过BeanPostProcessor给了我们一个机会对Spring管理的bean进行再加工。比如:我们可以修改bean的属性,可以给bean生成一个动态代理实例等等。一些Spring AOP的底层处理也是通过实现BeanPostProcessor来执行代理包装逻辑的。

2.3.2 常用的BeanPostProcessor接口
  • RequiredAnnotationBeanPostProcessor 它用于处理@Required注解。当我们一个Setter方法加入@Required后,表示必须设置参数,如果未设置则抛出BeanInitializationException异常。
  • AutowiredAnnotationBeanPostProcessor 这个后置处理器在3.x之后使用Spring框架的系统几乎都会使用,就是他在处理大名鼎鼎的@Autowired和@Value注解。