zoukankan      html  css  js  c++  java
  • Spring ApplicationContext(五)invokeBeanFactoryPostProcessors

    Spring ApplicationContext(六)BeanPostProcessor

    产生回顾一下 ApplicationContext 初始化的几个步骤:第一步是刷新环境变量;第二步是刷新 beanFactory 并加载 BeanDefinition;第三步是对 beanFactory 进行功能扩展,如增加 SPEL 支持和属性编辑器;第四步是留给子类实现的。

    上一节中向 Spring 中注册将执行了 BeanFactoryPostProcessor,本节则继续探讨一下 BeanPostProcessor 的注册及调用时机。

    public interface BeanPostProcessor {
        // 在初始化之前调用
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
        // 在初始化之后调用
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }
    
    1. BeanPostProcessor 什么时候注册?

      BeanFactory 和 ApplicationContext 容器的注册方式不大一样:若使用 BeanFactory,则必须要显示的调用其 addBeanPostProcessor() 方法进行注册;如果是使用 ApplicationContext,那么容器会在配置文件在中自动寻找实现了 BeanPostProcessor 接口的 Bean,然后自动注册。

    2. BeanPostProcessor 如何确保调用顺序?

      假如我们使用了多个的 BeanPostProcessor 的实现类,那么如何确定处理顺序呢?其实只要实现 Ordered 接口,设置 order 属性就可以很轻松的确定不同实现类的处理顺序了;
      接口中的两个方法都要将传入的 bean 返回,而不能返回 null,如果返回的是 null 那么我们通过 getBean() 方法将得不到目标。

    一、BeanPostProcessor 的注册

    源代码【AbstractApplicationContext】

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        // 6. 注册 BeanPostProcessor 后置处理器,在 getBean() 创建 bean 时调用
        registerBeanPostProcessors(beanFactory);
    
        /**
        * 1. 实例化剩余的所有非延迟加载单例对象
        * 2. 为什么说是剩余的?因为在上面的 registerBeanPostProcessors 中已经把所有 BeanPostProcessors 所有对象都已经实例化过了;
        * 3. 这加载的时候会判断 bean 是不是 FactoryBean 类型的
        *   3.1 如果是 FactoryBean 类型,则 getBean(&beanName),这里是把 FactoryBean 本身的对象给实例化了,而没有调它的 getObject 方法;
        *   3.2 如果不是 FactoryBean 类型,直接 getBean() 就行了;
        * 4. 还要判断是不是 SmartInitializingSingleton 接口,这个接口有个 afterSingletonsInstantiated 方法;
        */
        finishBeanFactoryInitialization(beanFactory);
    }
    
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    

    源代码【PostProcessorRegistrationDelegate】

    public static void registerBeanPostProcessors(
                ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 1. 此时 BeanDefinition 已经加载,只是 bean 还没有被实例化
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
        // 2. 记录日志用
        // 可能已经注册了部分 BeanFactoryPostProcessors 接口
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
        // 3. 按 PriorityOrdered internal Ordered nonOrdered 四个级别
        // 3.1 优先级最高的 BeanPostProcessors,这类最先调用;需要实现 PriorityOrdered 接口
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        // 3.2 内部 BeanPostProcessors
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        // 3.3 继承了 Ordered 接口,优先级比上面低一点
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        // 3.4 这就是普通的了,优先级最低
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }
    
        // 4. PriorityOrdered internal Ordered nonOrdered 分别排序、初始化、注册
        // 4.1 PriorityOrdered BeanPostProcessors
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
        // 4.2 Ordered BeanPostProcessors
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
        // 4.3 nonOrdered BeanPostProcessors
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    
        // 4.4 internal BeanPostProcessors
        //     注意重复注册会先删除先注册的元素加添加到集合最后面,影响执行顺序
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
    
    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
    

    源代码【AbstractBeanFactory】

    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
    
    @Override
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        // 如果已经注册则删除后重新注册,影响其执行顺序,如 internal 中的 MergedBeanDefinitionPostProcessor
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }
    }
    

    总结:

    (1) 最后 BeanPostProcessor 的注册顺序为 PriorityOrdered、Ordered、nonOrdered、internal,其中 internal 又分为 PriorityOrdered、Ordered、nonOrdered 三种顺序。

    二、BeanPostProcessor 实战

    class PriorityOrderTest implements BeanPostProcessor, PriorityOrdered {}
    class OrderTest implements BeanPostProcessor, Ordered {}
    class NoneTest implements BeanPostProcessor {}
    

    三、BeanPostProcessor 调用时机

    源代码【AbstractAutowireCapableBeanFactory】

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        //省略...
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // BeanPostProcessors 两个方法都在这里面
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    }
    
    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        // 省略 ...
        invokeAwareMethods(beanName, bean);
    
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 初始化前
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        try {
            // 初始化
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(ex);
        }
    
        if (mbd == null || !mbd.isSynthetic()) {
            // 初始化后
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }
    
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }
    

    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    video标签
    正则表达式
    BOM和DOM
    css样式属性
    js简介
    格式与布局
    CSS样式表
    表单
    redis学习心得之三-【java操作redis】
    redis学习心得之二【redis主从配置】
  • 原文地址:https://www.cnblogs.com/binarylei/p/10423552.html
Copyright © 2011-2022 走看看