Spring -- Bean/BeanPostProcessor/BeanFacotryPostProcessor

123 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

容器与Bean

1 Bean的生命周期

1.1 Bean生命周期各个阶段

首先明白对象实例化初始化两个阶段。

  1. 通过反射创建对象的过程为实例化
  2. 给创建的对象的成员变量赋值的操作为初始化

@PostConstruct与@PreDestroy可以额外操作Bean的生命周期

InstantiationAwareBeanPostProcessor与DestructionAwareBeanPostProcessor额外对Bean的生命周期方法进行增强

image-20220422112855713.png

postProcessBeforeInstantiation --> 构造方法(实例化) --> postProcessAfterInstantiation

--> postProcessProperties --> 依赖注入

--> postProcessBeforeInitialization --> 初始化(@PostConstruct) --> postProcessAfterInitialization

--> postProcessBeforeDestruction --> 销毁(@PreDestroy)

image-20220422141619856.png 管理Bean的声明周期的三种方法:

  1. 实现InitializingBean和DisposableBean接口
  2. 使用@Bean注解设置initMehtod与destroyMethod
  3. @PostContruct与@PreDestroy

ps. 字符串类型的变量不会通过@Autowire自动注入

// LifeCycleBean.java
@Component
public class LifeCycleBean {
    private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        log.debug("构造");
    }

    @Autowired
    public void autowire(@Value("${JAVA_HOME}") String home) {
        log.debug("依赖注入: {}", home);
    }

    @PostConstruct
    public void init() {
        log.debug("初始化");
    }

    @PreDestroy
    public void destroy() {
        log.debug("销毁");
    }
}
// MyBeanPostProcessor.java
// 打上Component注解,交给Spring容器管理。
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
    private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);

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

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.debug("<<<<<<<<<<<<< 实例化之前执行");
        }
        return null;
    }

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

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.debug("<<<<<<<<<<<<< 依赖注入阶段,@Autowired/@Value/@Resource");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.debug("<<<<<<<<<<<<< 初始化之前执行");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.debug("<<<<<<<<<<<<< 初始化之后执行");
        }
        return bean;
    }
}
// 启动类
@SpringBootApplication
public class A03Application {

    public static void main(String[] args){
        ConfigurableApplicationContext context = SpringApplication.run(A03Application.class, args);
        context.close();
    }
}

1.2 模板设计模式

会发现上述的实现方式就模板设计模式,给定了一个固定的框架,同时也提供了接口,允许用户进行扩展。

在一个方法中定义一个算法骨架,并将某些步骤推迟到子类/接口中实现。
public class TestMehtodTemplate {
    public static void main(String[] args){
        MyFactory myFactory = new MyFactory();
        myFactory.addBeanPostProcessor((obj -> {
            System.out.println("解析@Autowire");
        }));
        myFactory.addBeanPostProcessor((obj -> {
            System.out.println("解析@Resource");
        }));
        Object bean = myFactory.getBean();
    }

    static class MyFactory {
        private List<BeanPostProcessor> postProcessors = new ArrayList<>();

        public Object getBean() {
            // 静态部分
            Object object = new Object();
            System.out.println("实例化Bean");
            System.out.println("依赖注入其他Bean");
            // 动态部分
            for (BeanPostProcessor postProcessor : postProcessors) {
                postProcessor.inject(object);
            }
            System.out.println("初始化Bean");

            return object;
        }

        public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
            postProcessors.add(beanPostProcessor);
        }
    }

    interface BeanPostProcessor {
        void inject(Object obj);
    }
}