Spring生命周期看这就够了!
面对别人问你Spring的生命周期怎么回答他?
谈到 bean 的生命周期,概括为分为四个阶段:
1、bean的实例化 Instantiation
2、给属性值赋值 Populate
3、初始化 initialization
4、销毁 Destory
阅读源码发现在AbstractBeanFactory类中的doCreateBean()中有对这几个阶段的方法调用,忽略了无关代码,方便理解,如下:
// 忽略了无关代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 实例化阶段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性赋值阶段!
populateBean(beanName, mbd, instanceWrapper);
// 初始化阶段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
实例化和属性赋值对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。销毁阶段是在容器关闭时调用的,在ConfigurableApplicationContext类的close()中。
举例
下面,实现一下InitializingBean、BeanNameAware、ApplicationContextAware、BeanFactoryAware这几个接口,来重写对应接口下的方法。
首先写个Car实体类,分别实现InitializingBean接口的init、destroy方法,重写BeanNameAware 接口的setBeanName方法,ApplicationContextAware接口的setApplicationContext方法,BeanFactoryAware接口的setBeanFactory方法。
/*
* 一个类必须要有构造方法!!! FactoryBean
*/
public class Car implements InitializingBean ,BeanNameAware ,
ApplicationContextAware,BeanFactoryAware{
private String name;
private String beanName;
//1、jvm自动为这个类添加一个无参数的默认构造方法
//public Car() {}
//2、自己写构造方法,jvm不会自动添加构造方法了
public Car() {
//System.out.println("car实例化");
}
public Car(String name) {
super();
System.out.println("car实例化");
this.name = name;
}
/*初始化方法*/
public void init() {
System.out.println("car进行初始化。");
}
public void destroy() {
System.out.println("car进行销毁。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet 被调用的.....");
}
//重写BeanNameAware的方法
public void setBeanName(String name) {
this.beanName = name;
}
public String getBeanName() {
return beanName;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext:"+applicationContext);
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory====>"+beanFactory);
}
}
@Configuration
public class MainConfig {
@Bean(name="car",initMethod="init",destroyMethod="destroy")
public Car getCar() {
return new Car("大黄蜂");
}
@Bean
public BeanPostProcessor getBeanPostProcessor() {
return new NdBeanPostProcessor();
}
@Bean
public InstantiationAwareBeanPostProcessorAdapter getIntanceAware(){
return new MyInstantiationAwareBeanPostProcessorAdapter();
}
}
在实例化前后,初始化前后进行干预。
public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("car")){
System.out.println("【实例化】【前】干预"+beanName);
}
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("car")){
System.out.println("【初始化】【前】干预"+beanName);
}
return super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("car")){
System.out.println("【初始化】【后】干预"+beanName);
}
return bean;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("car")){
System.out.println("【实例化】【后】干预"+beanName);
}
return super.postProcessAfterInstantiation(bean, beanName);
}
}
四个主生命周期
(1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()
1.实例化
(2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter
.postProcessAfterInstantiation()
2.填充属性(给属性赋值)
(1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization()
(3) InitializingBean.afterPropertiesSet()
3.初始化(比如准备资源文件)
(2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization()
4.销毁(释放资源—对象从内存销毁)
/*
四个主生命周期
(1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()
1.实例化
(2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation()
2.填充属性(给属性赋值)
()
(1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization()
(3) InitializingBean.afterPropertiesSet()
3.初始化(比如准备资源文件)
(2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization()
4.销毁(释放资源---对象从内存销毁)
N个接口
1、干预多次
1)BeanPostProcessor
2、干预一次
1)Aware
*/
public class TestLifeCycle {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(MainConfig.class);
Car car = (Car) context.getBean("car");
System.out.println(car);//toString
System.out.println("car bean的名字叫:"+car.getBeanName());
// Car car1 = new Car();//不会干预 因为你不是交给spring ioc容器进行实例化
}
}
后置处理器的postProcessBeforeInitialization、postProcessBeforeInitialization方法。
//后置处理器
public class NdBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("NdBeanPostProcessor在car对象初始化之 前 调用");
if(beanName.equals("car")) {
return new CglibInterceptor().getInstance(bean.getClass());
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("NdBeanPostProcessor在car对象初始化之 后 调用");
return bean;
}
}
CGLIB动态代理拦截器,
public class CglibInterceptor implements MethodInterceptor{
public Object getIntance(Class clazz) {
Enhancer enchncer = new Enhancer();
enchncer.setSuperclass(clazz);
enchncer.setCallback(this);
return enchncer.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("-----鉴权前-----");
Object result = proxy.invokeSuper(obj, args);
System.out.println("-----鉴权后-----");
return result;
}
}
运行结果如图所示,
总结为
Bean 生命周期的整个执行过程描述如下。
1)根据配置情况,如果在配置文件内配置了InstantiationAwareBeanPostProcessorAdapter类,在干预类中继承了该类,那么可重写该类的postProcessBeforeInstantiation()方法。
2)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
3)如果在配置文件内配置了
InstantiationAwareBeanPostProcessorAdapter类,在干预类中继承了该类,
那么可重写该类的postProcessAfterInstantiation()方法。
4)利用依赖注入完成 Bean 中所有属性值的配置注入。
5)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
6)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用(即将BeanFactory对象传给setBeanFactory方法)。
7)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
8)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作。此处非常重要,Spring 的 AOP 就是利用它实现的。
9)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
10)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
11)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
12)如果在配置文件的Bean标签 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在配置文件的Bean标签指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
13)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
另外,个人从[https://www.jianshu.com/p/1dec08d290c1]文章中受益不少,部分转载其中,如有侵权,可沟通删除。读者读后看哪些需要补充的,欢迎不吝赐教。