Bean的生命周期


Bean的生命周期



第一步:**

 /**
实例化BeanFactoryPostProcessor该接口,这个接口的方法为 postProcessBeanFactory是在bean创建之前执行的,可以修改bean的元数据也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。*/
 void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;

第二步:

上述图中的描述那个接口已过时,现在使用的接口为

InstantiationAwareBeanPostProcessor

在执行构造器之前先执行这个接口的postProcessBeforeInstantiation方法

//这个对象返回的方法 会替换原有的bean
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    return null;
}

然后执行bean的构造器

然后执行

//这里返回false会跳过依赖注入阶段
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    return true;
}

第三步:依赖注入

进行依赖注入相关的增强 首先执行的还是InstantiationAwareBeanPostProcessor 这个接口中的方法

//解析如 @Autowired、@Value、@Resource
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
    return null;
}

依赖注入后如果这个bean实现了BeanNameAware接口或者BeanFactoryAware接口或者其他aware会进行执行,只要是设置bean的名字之类的一些配置

第四步:初始化

/*初始化之前执行postProcessBeforeInitialization

* 这里返回的对象会替换掉原本的 bean
* 如 @PostConstruct、@ConfigurationProperties*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (beanName.equals("lifeCycleBean"))
        System.out.println("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
    return bean;
}

然后调用初始化方法

@PostConstruct
public void init(){
    System.out.println("初始化");
}
//初始化之后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (beanName.equals("lifeCycleBean"))
        System.out.println("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
    return bean;
}

第五步:销毁

执行销毁之前的方法 实现的接口是

 DestructionAwareBeanPostProcessor 

首先执行这个方法

@Override
public boolean requiresDestruction(Object bean) {
    Class<?> aClass = bean.getClass();
    if(aClass==LifeCycleBean.class){
        System.out.println("你看我何时被销毁");
    }
    return true;
}
//最终被销毁
@PreDestroy
public void destory(){
    System.out.println("销毁");
}

代码演示

package com.zf.reviewspring.a03;

        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.BeansException;
        import org.springframework.beans.factory.BeanFactory;
        import org.springframework.beans.factory.BeanFactoryAware;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.stereotype.Component;

        import javax.annotation.PostConstruct;
        import javax.annotation.PreDestroy;

/**
 * 执行顺序
 * 构造---注入---初始化--销毁
 */
@Component
public class LifeCycleBean  implements BeanFactoryAware {

    private static final Logger log= LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        System.out.println("构造");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("----------------BeanFactory");
    }

    @Autowired
    //也是进行bean注入  如果不加@Value则不是  如果加了@Value是以值进行诸如
    public void autowired(@Value("${JAVA_HOME}")String home){
        System.out.println("依赖注入:{}"+home);
    }


    /**
     * @PostConstruct基本:
     * @PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。
     *
     *
     * Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
     * 通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
     * Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

     */
    @PostConstruct
    public void init(){
        System.out.println("初始化");
    }
    @PreDestroy
    public void destory(){
        System.out.println("销毁");
    }
}
package com.zf.reviewspring.a03;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.*;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanFactoryPostProcessor, InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {


    private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);

    /**
     * 实现该接口,可以在spring的bean创建之前,修改bean的定义属性。
     * 也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,
     * 并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。
     * 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。

     * @param configurableListableBeanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("\n" +
                "        System.out.println(\"调用MyBeanFactoryPostProcessor的postProcessBeanFactory\")");
    }


    @Override
    public boolean requiresDestruction(Object bean) {
        Class<?> aClass = bean.getClass();
        if(aClass==LifeCycleBean.class){
            System.out.println("你看我何时被销毁");
        }
        return true;
    }




    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            System.out.println("<<<<<< 销毁之前执行, 如 @PreDestroy");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            System.out.println("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            System.out.println("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
         //  return false;
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            System.out.println("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            System.out.println("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            System.out.println("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
        return bean;
    }
}


System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory")


<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean
构造
<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段
<<<<<< 依赖注入阶段执行,@Autowired@Value@Resource
依赖注入:{}D:\tools\jdk1.8.0_191
----------------BeanFactory
<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean,@PostConstruct@ConfigurationProperties
初始化
<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强
你看我何时被销毁
你看我何时被销毁
2022-05-10 20:57:23.728  INFO 88376 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-05-10 20:57:23.739  INFO 88376 --- [           main] com.zf.reviewspring.a03.A03Application   : Started A03Application in 2.107 seconds (JVM running for 3.627)
com.zf.reviewspring.a03.LifeCycleBean@3ff57625
<<<<<< 销毁之前执行,@PreDestroy
销毁

Process finished with exit code 0

文章作者: 蛰伏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 蛰伏 !
  目录