Spring IOC bean的生命周期
1. 解析xml bean封装成beanDefination对象
2. ⼯⼚初始化(BeanFactory)
3. bean的生命周期
基本图示意
基本步骤
- 如果有bean实现了InstantiationAwareBeanPostProcessor 会调用Bean实例化之前扩展点
- Spring容器对bean进行实例化,默认bean是单例
Bean实例化之后扩展点 - InstantiationAwareBeanPostProcessor中方法的属性处理
Spring对bean进行依赖注入 - 如果bean实现了BeanNameAware接口,Spring将bean的id传给setBeanName()方法;
如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来; - 如果有bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用
- 如果bean实现了InitializingBean接口,Spring将调用它的afterPropertiesSet接口方法,如果有init-method方法则被调用
- 如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用
- 注册销毁回调函数
- bean已经准备就绪,可以被应用程序使用
- 若bean实现了DisposableBean接口,Spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用
代码实现Spring生命周期的接口方法执行顺序的演示
普通类实现Spring生命周期中接口
/**
* @author lane
* @date 2021年03月26日 下午3:35
*/
public class Apple implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {
private int id;
private String color;
public void setId(int id) {
this.id = id;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Apple{" +
"id=" + id +
", color='" + color + '\'' +
'}';
}
@Override
public void setBeanName(String s) {
System.out.println("我的名字是"+s);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("我是在哪个工厂创建的"+beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("高级容器接口"+applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("执行生命周期中的afterPropertiesSet");
}
public void initMethod(){
System.out.println("执行了init-method 方法");
}
@PostConstruct
public void postConstruct(){
System.out.println("执行postConstruct 注解的方法");
}
@PreDestroy
public void preDestory(){
System.out.println("执行preDestroy方法");
}
}
Spring的后置处理器之BeanPostProcessor
/**
* 拦截实例化之后的对象(实例化了且属性注入了)
* @author lane
* @date 2021年03月26日 下午4:49
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//默认拦截所有的,指定某一个bean
if ("apple".equalsIgnoreCase(beanName)){
System.out.println("MyBeanPostProcessor 的before方法执行了"+beanName+"被拦截了,挺急的");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("apple".equalsIgnoreCase(beanName)){
System.out.println("MyBeanPostProcessor 的after方法执行了"+beanName+"被拦截了,不用急");
}
return bean;
}
}
具体调用bean
Apple apple2= (Apple) applicationContext.getBean("apple");
System.out.println(apple2);
打印结果
我的名字是apple
我是在哪个工厂创建的org.springframework.beans.factory.support.DefaultListableBeanFactory@563f38c4:
高级容器接口org.springframework.context.support.ClassPathXmlApplicationContext@dd3b207, started on Fri Mar 26 16:26:26 CST 2021MyBeanPostProcessor 的before方法执行了apple被拦截了,挺急的
执行postConstruct 注解的方法
执行生命周期中的afterPropertiesSet
执行了init-method 方法
MyBeanPostProcessor 的after方法执行了apple被拦截了,不用急