这里知识粗略的介绍一下bean的生命周期,先看一下图:
用简单的话来说就是:
-
第一步:通过构造器创建
bean
实例,默认是无参构造器 -
第二步:设置bean的属性值和引入其他的bean(
spring的循环依赖
),如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID),如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身,由于我们是通过
@value
方式赋值,所以第二步直接跳过了 -
第三步:执行初始化方法,如果对象实现了
BeanPostProcessor
接口,通过这个后置处理器实现public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化方法执行前执行"); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化方法执行后执行"); return bean; }
这两个方法,就会在初始化之前/之后分别调用
-
第四步:获取bean实例
-
第五步:执行销毁方法
下面我们通过一个例子来具体看一下这个过程:
测试的实体类:
@Component
public class person implements BeanPostProcessor,DisposableBean, InitializingBean {
@Value("威猛先生")
private String name;
public person() {
System.out.println("第一步,调用默认构造器");
}
public person(String name) {
this.name = name;
System.out.println("第一步,调用有参构造器");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// @PostConstruct
// public void initMethod(){
// System.out.println("第三步,调用初始化方法");
// }
//
// @PreDestroy
// public void destroyMethod(){
// System.out.println("第五步,执行销毁的方法");
// }
public void destroy() throws Exception {
System.out.println("第五步,执行销毁的方法");
}
public void afterPropertiesSet() throws Exception {
System.out.println("第三步,调用初始化方法");
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法执行前执行");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法执行后执行");
return bean;
}
}
项目结构图:
main方法:
ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);
person p = (person) ac.getBean("person");
System.out.println("第四步,获取bean实例");
((AnnotationConfigApplicationContext)ac).close();
看输出结果:
第一步,调用默认构造器
初始化方法执行前执行
第三步,调用初始化方法
初始化方法执行后执行
第四步,获取bean实例
第五步,执行销毁的方法
结果和我们想的一样,这里需要提一点:通过实现这两个
DisposableBean, InitializingBean
接口来创建初始化方法和销毁方法是一种方式,但是通过注解更简单,也就是刚才实体类中注释的部分:
// @PostConstruct
// public void initMethod(){
// System.out.println("第三步,调用初始化方法");
// }
//
// @PreDestroy
// public void destroyMethod(){
// System.out.println("第五步,执行销毁的方法");
// }
总结:
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
-
1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
-
2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
-
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
-
4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用
当我们的应用上下文被加载了,这时候bean容器也随之加载,bean也被创建(ApplicationContext方式),在容器销毁前bean都会一直存在容器中,直到该上下文容器被销毁,bean生命周期也就随之结束了