Spring中Bean的生命周期
同样是《Spring 3.x企业应用开发实战》这本书所写的内容,今天看完以后想做一个总结。
首先我们大家应该知道spring 中有三种供 spring中bean 生存的容器: BeanFactory 、 ApplicationContext 、webApplicationContext 。其中ApplicationContext 和 webApplicationContext 基本一样,webApplicationContext就是有一些web专用的东西。所有这里就只介绍BeanFactory 和 ApplicationContext 。
理解springBean 的生命周期主要通过两个层面来理解。其一是 Bean 的作用范围,其一是实例化 Bean 时所经历的一系列阶段。
一、 BeanFactory
下图为BeanFactory 中 bean 生命周期的完整过程(图来自《Spring 3.x企业应用开发实战》)
以下按照顺序写一下调用的过程分别调用了哪些方法,为了方便理解,我用红字写了一下个人的猜测翻译理解:
1.当调用者通过 getBean(beanName)向 容器请求Bean 时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例 bean 之前,将调用该接口的 postProcessBeforeInstantiation()方法。
实例化以前的操作
2.根据配置情况调用 Bean构造函数或工厂方法实例化 bean
3.如果容器注册了 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例 bean 之后,调用该接口的 postProcessAfterInstantiation()方法,可以在这里对已经实例化的对象进行一些操作。
其实观察的仔细一点,就会发现1和3是同一个InstantiationAwareBeanPostProcessor接口,只不过调用的方法一个是postProcessBeforeInstantiation()和一个是postProcessAfterInstantiation(),一个before一个after一前一后,分别在实例化bean这个操作的前后,Instantiation这个单词就是实例化的意思。
4.如果Bean配置了属性信息,在设置每个属性之前将调用InstantiationAwareBeanPostProcess接口的 postProcessPropertyValues ()方法 。
于是我们发现又是和1、3同一个接口,只不过换了一个方法postProcessPropertyValues,字面上就能看出和属性相关,是设置属性前的操作
5.设置属性值
6.如果 Bean 实现了 org.springframework.beans.factory.BeanNameAware 接口,将调用 Bean 的 setBeanName() 方法传递 Bean 的 ID 。
设置完属性,首先是BeanNameAware的setBeanName()方法,设置bean名称。
7.如果 Bean 实现了 org.springframework.beans.factory.BeanFactoryAware 接口,将调用 setBeanFactory() 方法传入工厂自身。
然后是 BeanFactoryAware的setBeanFactory() 方法,设置bean实例。
8.如果 BeanPostProcessor 和 Bean 关联,那么 将调用org.springframework.beans.factory.config.BeanPostProcessor的postProcessBeforeInitialzation() 方 对 bean进行加工操作,与spring 的 AOP 有关。
这个同样是对bean的处理,BeanPostProcessor接口的postProcessBeforeInitialzation()方法。
9.如果bean 实现了 InitializingBean 接口,将调用 afterPropertiesSet()方法
InitializingBean接口的afterPropertiesSet()方法
10.如果Bean 指定了 init-method 方法,它将被调用。
init-method 方法
11.如果有BeanPsotProcessor 和 Bean 关联,那么它们的 postProcessAfterInitialization() 方法将被调用。 到这个时候, Bean 已经可以被应用系统使用了 。
与8相对应,又是一个前一后,一个before一个after
12-a.如果在<bean> 中指定了该 bean 的作用范围为 scope="prototype", 将 bean 的调用者,调用者管理该 bean 的生命周期,spring 不在管理该 bean 。
spring不管理该bean的情况为scope="prototype",此处12为分叉,有两种情况
12-b.如果在<bean> 中指定了该 bean 的作用范围为 scope="singleton", 则将该 bean 放入 springIOC 的缓存池中,将触发 spring 对该 bean 的生命周期管理。
spring管理该bean的情况为scope="singleton",此处12为分叉,有两种情况
13-a.如果 Bean 实现了 DisposableBean 接口, afterPropertiesSet()方法()被调用。
14-a.直接通过destroy-method销毁
14-b 这个bean自己的管理者如何销毁,spring不管。
总结:
Bean的完整生命周期从 spring 容器开始实例化 bean 开始,到销毁。可以从三点来理解
1、 bean自身的方法:包括构造方法、 set 方法、 init-method 指定的方法、 destroy-method 指定的方法
2、 Bean级生命周期接口方法:如 BeanNameAware 、 BeanFactoryAware 等这些接口方法由 bean类实现。
3、 容器级生命周期接口方法:上图中带星的。有InstantiationAwareBeanPostProcessor 、 BeanPostProcessor 等。一般称为后处理 器。他们一般不由bean 本身实现,独立存在,注册到 spring 容器中。 Spring 通过接口反射预先知道,当 spring 容器创建任何 bean 时,这些后处理器都会发生作用。所以他们是全局的,用户可以通过编码对只感兴趣的 bean 进行处理。
Bean级生命周期接口和容器级生命周期接口是个性和共性辩证统一的思想,前者解决 bean 的个性化处理问题,而后者解决容器中某些 bean 共性化处理问题。
二、 ApplicationContext
下图描述了ApplicationContext 的生命周期
通过上图很容易发现其实应该上下文和BeanFactory 只是多了一个接口, 如果Bean 实现了 ApplicationContextAwre接口, setApplicationContext() 方法被调用。
在上图的7和8之间
如果配置文件中生明了工厂后处理器接口 BeanFactoryPostProcessor的实现类,则应用上下文在装配配置文件之后初始化 bean 之前将调用该接口对配置信息进行加工。
在上图中的1之前
还有应该上下文的这些后处理器只要和普通的bean 一样配置在 spring 配置文件中就行了,不需要事先声明。
而BeanFactory必须要声明比较麻烦
总结:
没啥好总结的,理解都在上面了,如有错误请指正。