Spring 5企业级开发实战
上QQ阅读APP看书,第一时间看更新

2.4 Spring IoC容器中Bean的生命周期

Spring IoC容器管理的Bean默认都是单利设计模式的(参见本书附录),即每个Bean只有一个实例化的Bean对象存在于Spring IoC容器中,因此Spring IoC容器需要负责管理Bean的产生、使用和销毁等生命周期。

Spring IoC容器中的Bean的生命周期可以分为以下4类:

• Bean自身方法。

• Bean生命周期接口方法。

• 容器级生命周期接口方法。

• 工厂后处理器接口方法。

各个阶段涉及的具体接口和方法如表2-1所示。

表2-1 各阶段具体接口和方法

下面先以Bean自身方法和Bean生命周期接口方法为例,演示其各个生命周期的执行时序。

• init-method:指定某个方法在Bean实例化完成,依赖关系设置结束后执行。

• destroy-method:指定某个方法在Bean销毁之前被执行。

• InitializingBean接口:指定在Bean实例化完成,依赖关系设置结束后执行(在init-method之前执行)。

• DiposableBean接口:指定某个方法在Bean销毁之前被执行(在destory-method之前执行)。

• ApplicationContextAware接口:在实例化Bean时,为Bean注入ApplicationContext。

• BeanNameAware接口:在实例化Bean时,为Bean注入beanName。

以下代码BeanLifecycle将实现上述4个接口InitializingBean、DiposableBean、ApplicationContextAware和BeanNameAware,并通过在XML文件中配置该Bean的init-method和destroy-method。通过BeanLifecycle例子将可以更加清晰地阐述Bean自身方法和Bean生命周期接口方法的生命周期。

如上述代码中的注释所示,BeanLifecycle这个Bean的生命周期将按照序号1~8顺序执行。下面是对BeanLifecycle准备的测试代码:

这段测试代码很简单,就是通过从Spring IoC容器中注入的BeanLifecycle对象,调用其sayHello()方法。测试代码运行后的结果如图2-11所示。

图2-11 Bean自身方法和Bean生命周期接口方法生命周期测试图

通过执行结果可以得到Bean自身方法和Bean生命周期接口方法的执行时序:

(1)执行构造器。

(2)执行BeanNameAware接口的setBeanName(String name)方法。

(3)执行ApplicationContextAware接口的setApplicationContext(ApplicationContextapplication Context)方法。

(4)执行InitializingBean接口的afterPropertiesSet()方法。

(5)执行init-method指定的方法。

(6)执行运行时Bean中的业务方法。

(7)执行DisposableBean接口的destroy()方法。

(8)执行destroy-method指定的方法。

Bean自身方法和Bean生命周期接口方法执行的生命周期时序图如图2-12所示。

图2-12 Bean自身方法和Bean生命周期接口方法生命周期时序图

下面将介绍容器级生命周期接口方法的执行时序。容器级生命周期接口方法有InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口,一般也将其实现类称为后处理器。容器级生命周期接口的实现独立于Spring IoC容器中的Bean,其是以容器扩展的形式注册到Spring中的。无论Spring IoC管理任何的Bean,这些后处理器都会发生作用。因此后处理器影响范围是全局的Spring IoC容器中的Bean。用户可以通过编写合理的后处理器来实现感兴趣的Bean加工处理逻辑。

• BeanPostProcessor接口:此接口的方法可以对Bean的属性进行更改。

• InstantiationAwareBeanPostProcessor接口:此接口可以在Bean实例化前、Bean实例化后分别进行操作,也可以对Bean实例化之后进行属性操作(为BeanPostProcessor的子接口)。

• InstantiationAwareBeanPostProcessorAdapter:适配器类。

BeanPostProcessor、InstantiationAwareBeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter三者的关系如图2-13所示。

图2-13 BeanPostProcessor相关类图

如图2-13所示,InstantiationAwareBeanPostProcessorAdapter最终实现了BeanPostProcessor这个顶级接口。下面以InstantiationAwareBeanPostProcessorAdapter为例,讲解容器级生命周期接口方法的执行时序。下面代码将通过ContainerLifecycle类继承InstantiationAwareBean-PostProcessorAdapter来阐述容器级生命周期接口方法的执行时序,具体代码如下:

如上代码段所示,ContainerLifecycle类继承了InstantiationAwareBeanPostProcessorAdapter,重写了其中postProcessBeforeInstantiation、postProcessPropertyValues和postProcessAfterInitialization方法。其执行顺序如下。

• ContainerLifecycle:构造器最先执行。

• postProcessBeforeInstantiation:接口方法和实例化Bean之前调用。

• postProcessPropertyValues:设置某个属性时调用。

• postProcessAfterInitialization:接口方法和实例化Bean之后调用。

测试代码中,还是以上例的BeanLifecycle类为例,调用BeanLifecycle类的sayHello()方法,测试代码如下:

运行单元测试,测试结果如图2-14所示。

下面将介绍的是工厂级生命周期接口方法,工厂级生命周期接口方法涉及到的有BeanFactoryPostProcessor接口。下面将通过实现BeanFactoryPostProcessor接口来分析。

图2-14 容器级生命周期接口方法结果

工厂级生命周期接口的生命周期,实现代码如下:

测试代码将所有级别生命周期接口进行统一测试,以方便观察完整的Bean生命周期的执行时序:

测试效果图如图2-15所示。

图2-15 完整的生命周期执行顺序