理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。
生命周期流程图
Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean,这其中包含了一系列关键点。
示例
创建两个 bean,让其相互依赖。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
public class BeanADemo implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, BeanPostProcessor, DisposableBean, InitializingBean {
private BeanBDemo beanBDemo;
public BeanADemo() {
System.out.println("Constructor BeanADemo invoked");
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName " + name + " invoked");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory invoked");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware setApplicationContext invoked");
}
@PostConstruct
public void postConstructMethod() {
System.out.println("Post Construct BeanADemo invoked");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet BeanADemo invoked");
}
public void initMethod() {
System.out.println("init-method BeanADemo invoked");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessBeforeInitialization BeanADemo invoked");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessAfterInitialization BeanADemo invoked");
return bean;
}
@PreDestroy
public void preDestroyMethod() {
System.out.println("Pre Destroy BeanADemo invoked");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean destroy BeanADemo invoked");
}
public void destroyMethod() {
System.out.println("destroy-method BeanADemo invoked");
}
@Resource
public void setBeanBDemo(BeanBDemo beanBDemo) {
System.out.println("setBeanBDemo invoked");
this.beanBDemo = beanBDemo;
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
public class BeanBDemo implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, BeanPostProcessor, DisposableBean, InitializingBean {
private BeanADemo beanADemo;
public BeanBDemo() {
System.out.println("Constructor BeanBDemo invoked");
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName " + name + " invoked");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory B invoked");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware setApplicationContext invoked");
}
@PostConstruct
public void postConstructMethod() {
System.out.println("Post Construct BeanBDemo invoked");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet BeanBDemo invoked");
}
public void initMethod() {
System.out.println("init-method BeanBDemo invoked");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessBeforeInitialization BeanBDemo invoked");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessAfterInitialization BeanBDemo invoked");
return bean;
}
@PreDestroy
public void preDestroyMethod() {
System.out.println("Pre Destroy BeanBDemo invoked");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean destroy BeanBDemo invoked");
}
public void destroyMethod() {
System.out.println("destroy-method BeanBDemo invoked");
}
@Resource
public void setBeanADemo(BeanADemo beanADemo) {
System.out.println("setBeanADemo invoked");
this.beanADemo = beanADemo;
}
}
通过 xml 配置 bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启基于注解的配置 -->
<context:annotation-config/>
<bean class="demo.BeanADemo" init-method="initMethod" destroy-method="destroyMethod"/>
<bean class="demo.BeanBDemo" init-method="initMethod" destroy-method="destroyMethod"/>
</beans>
启动 Spring 容器及关闭。
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
public static void main(String[] args) {
ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("demo.xml");
ct.close();
}
}
执行结果如下:
Constructor BeanADemo invoked Constructor BeanBDemo invoked setBeanADemo invoked setBeanName demo.BeanBDemo#0 invoked setBeanFactory B invoked ApplicationContextAware setApplicationContext invoked Post Construct BeanBDemo invoked InitializingBean afterPropertiesSet BeanBDemo invoked init-method BeanBDemo invoked setBeanBDemo invoked setBeanName demo.BeanADemo#0 invoked setBeanFactory invoked ApplicationContextAware setApplicationContext invoked Post Construct BeanADemo invoked InitializingBean afterPropertiesSet BeanADemo invoked init-method BeanADemo invoked BeanPostProcessor postProcessBeforeInitialization BeanADemo invoked BeanPostProcessor postProcessBeforeInitialization BeanBDemo invoked BeanPostProcessor postProcessAfterInitialization BeanADemo invoked BeanPostProcessor postProcessAfterInitialization BeanBDemo invoked BeanPostProcessor postProcessBeforeInitialization BeanADemo invoked BeanPostProcessor postProcessBeforeInitialization BeanBDemo invoked BeanPostProcessor postProcessAfterInitialization BeanADemo invoked BeanPostProcessor postProcessAfterInitialization BeanBDemo invoked Pre Destroy BeanBDemo invoked DisposableBean destroy BeanBDemo invoked destroy-method BeanBDemo invoked Pre Destroy BeanADemo invoked DisposableBean destroy BeanADemo invoked destroy-method BeanADemo invoked
可以得知,Spring IoC 容器中 bean 的初始化,首先调用所有 bean 的构造器,然后针对一个 bean 进行相应的初始化顺序,具体如下:
初始化时:构造器 Construct -> 属性注入 -> BeanNameAware 接口实现方法 -> BeanFactoryAware 接口实现方法 -> ApplicationContextAware 接口实现方法 -> @PostConstruct -> InitializingBean 接口实现方法 -> bean 定义的 initMethod;
销毁时:@PreDestroy -> DisposableBean 接口实现方法 -> bean 定义的 destoryMethod。