bean的生命周期是指spring中一个bean创建过程和销毁过程所经历步骤。其中bean的创建过程是重点。
我们可以利用bean的生命周期机制对bean进行自定义加工
beandefinition对象定义->构造方法执行->实例化构造方法,反射获得对象->属性填充,给属性自动填充->初始化,给其他属性赋值校验->初始化后,AOP生成代理对象
- beanDefinition对象定义:通过beanClassName属性确定bean的类型,从而实例化对象。
- 实例化构造方法,反射获得对象:可以使用BeanPostProcessor进行干预。
- 属性填充:实例化后的对象是不完整的对象,某些属性还没有填充,也就是spring还没有自动给属性赋值,属性填充就是spring自动注入或者依赖注入的过程。
- 初始化:在给对象填充之后,spring提供了初始化,我们可以利用初始化机制对bean进行自定义加工,比如可以利用initiallizingBean接口对bean做一些改造。
- 初始化后是bean创建的最后一个步骤,AOP机制就是在这个步骤中通过BeanPostProcessor机制实现的,初始化后可以得到真正的bean对象。
接下来通过一个例子看一下:
@Component
public class DiscountInfo implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware {
@Autowired
private CheckEcloudVo checkEcloudVo;
public DiscountInfo() {
System.out.println("DiscountInfo 的构造方法执行...");
System.out.println("构造方法:checkEcloudVo="+checkEcloudVo);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 的afterPropertiesSet执行了...");
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct 修饰的init方法执行了。。。");
}
@PreDestroy
public void destory(){
System.out.println("@PreDestroy 修饰的destory方法执行了。。。");
}
@Override
public void setBeanName(String name) {
System.out.println("BeanNameAware接口的setBeanName方法执行了:"+name);
System.out.println("BeanNameAware接口 :checkEcloudVo"+checkEcloudVo);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware接口的setBeanFactory方法执行了:"+beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware接口的setApplicationContext方法执行了:"+applicationContext);
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean接口的destroy方法执行了...");
}
}
public class MyFactoryBean implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean.getClass()+":BeanPostProcessor 的 postProcessBeforeInitialization 方法执行...");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean.getClass()+":BeanPostProcessor 的 postProcessAfterInitialization 方法执行...");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
执行结果:
DiscountInfo 的构造方法执行...
//说明此时还没有依赖注入
构造方法:checkEcloudVo=null
BeanNameAware接口的setBeanName方法执行了:discountInfo
//说明此时已经依赖注入了
BeanNameAware接口 :checkEcloudVoCheckEcloudVo(customerName=null, customerNum=null, custType=null, prodordCharacters=null, hostCompanyNum=null, charNum=null)
BeanFactoryAware接口的setBeanFactory方法执行了:org.springframework.beans.factory.support.DefaultListableBeanFactory@78e94dcf: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,myConfig,checkEcloudVo,discountInfo,com.bboss.business.ecloud.config.MyFactoryBean,advice,beanNameAutoProxyCreator]; root of factory hierarchy
ApplicationContextAware接口的setApplicationContext方法执行了:org.springframework.context.annotation.AnnotationConfigApplicationContext@30a3107a: startup date [Tue Dec 07 15:23:36 CST 2021]; root of context hierarchy
class com.bboss.business.ecloud.bean.DiscountInfo:BeanPostProcessor 的 postProcessBeforeInitialization 方法执行...
@PostConstruct 修饰的init方法执行了。。。
InitializingBean 的afterPropertiesSet执行了...
DiscountInfo(checkEcloudVo=CheckEcloudVo(customerName=null, customerNum=null, custType=null, prodordCharacters=null, hostCompanyNum=null, charNum=null))
以下三种方式可以互相替换
- @bean的init-method、destory-mothod
- 实现initializingBean和disposableBean
- 使用JSR250的@PostConstruct、@PreDestory
结合bean的生命周期,我们可以在bean的创建过程中进行扩展,下一篇文章我们对spring的启动扩展进行总结以及之后我们对每一个扩展点进行代码解析!