BeanFactoryPostProcessor详解

原文地址

  • BeanFactoryPostProcessor接口与 BeanPostProcessor接口类似,可以对bean的定义(配置元数据)进行处理;也就是spring ioc运行BeanFactoryPostProcessor在容器实例化任何其他的bean之前读取配置元数据,并有可能修改它;如果业务需要,可以配置多个BeanFactoryPostProcessor的实现类,通过”order”控制执行次序(要实现Ordered接口)。
  • 二、使用

    • spring-base.xml配置
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xmlns:tx="http://www.springframework.org/schema/tx"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
    
    
         >
    
    
    
      <!-- spring ioc部分 start -->
        <bean id ="myTestBean" class= "com.zzq.core.test.entity.MyTestBean" >
    
        </bean>
    
    
          <bean id ="customBeanFactoryPostProcessor" class= "com.zzq.core.test.processor.CustomBeanFactoryPostProcessor" ></bean>
    
        <!-- spring ioc部分 end -->
    </beans>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • CustomBeanFactoryPostProcessor.java
    package com.zzq.core.test.processor;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.GenericBeanDefinition;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    
    
    /**
     * 和BeanPostProcessor原理一致,Spring提供了对BeanFactory进行操作的处理器BeanFactoryProcessor,简单来说就是获取容器BeanFactory,这样就可以在真正初始化bean之前对bean做一些处理操作。
     * 允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
     * **/
    public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("postProcessBeanFactory");
            //获取BeanDefinition   
           /* TestService testService = (TestService) beanFactory.getBean("testServiceImpl");  
            //System.out.println("得到 testService ");
            ////testService.doMessage(); */
    
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myTestBean");
            System.out.println("修改属性name值");
            beanDefinition.getPropertyValues().add("name", "liSi");
    
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • MyTestBean.java
    package com.zzq.core.test.entity;
    
    public class MyTestBean {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 运行的主函数BootStrap.java
    package com.zzq.core.test;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.zzq.core.test.entity.MyTestBean;
    
    public class BootStrap {
    
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "spring-base.xml");
    
            System.out.println(context.getBean("myTestBean") +  "--" + ((MyTestBean)context.getBean("myTestBean")).getName());
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 运行结果,对象的name属性已被更改。
      BeanFactoryPostProcessor详解

    三、查看源码

    • 从ClassPathXmlApplicationContext开始到它父类AbstractApplicationContext的refresh方法。
    public void refresh() throws BeansException, IllegalStateException {
            //来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
            synchronized (this.startupShutdownMonitor) {
    
                ...........................
                    // Allows post-processing of the bean factory in context subclasses.
                     // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
                     // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
    
                     // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
                     // 具体的子类可以在这步的时候根据吱声业务添加或修改一些特殊的 beanFactory属性
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    ...........................
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                     // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
                    destroyBeans();
    
                    // Reset 'active' flag.
                    //取消刷新的标志
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                     // 把异常往外抛
                    throw ex;
                }
            }
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 省略了部分代码,我们此次要关注的就是invokeBeanFactoryPostProcessors(beanFactory);方法。
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<String>();
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
                List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                        new LinkedList<BeanDefinitionRegistryPostProcessor>();
                //getBeanFactoryPostProcessors()大部分情况下里面元素是空的,所以主要还是走下面beanFactory.getBeanNamesForType方法得到处理器
                for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryPostProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryPostProcessors.add(registryPostProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
                Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
                        beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
                List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
                        new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
                OrderComparator.sort(registryPostProcessorBeans);
                for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
                    postProcessor.postProcessBeanDefinitionRegistry(registry);
                }
                invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
                processedBeans.addAll(beanMap.keySet());
            }
            else {
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            //根据BeanFactoryPostProcessor接口得到它的实现类
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            //将BeanFactoryPostProcessor处理器分成几种来执行 priorityOrderedPostProcessors  orderedPostProcessorNames  nonOrderedPostProcessorNames
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                else if (isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            OrderComparator.sort(priorityOrderedPostProcessors);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            OrderComparator.sort(orderedPostProcessors);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            //最后,调用所有其他后处理器。
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
    
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 一般情况下不会走到for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {里面,getBeanFactoryPostProcessors()元素为空(如果一定要让它走这儿的话,可以自己继承ClassPathXmlApplicationContext,重写里面的postProcessBeanFactory方法,使用addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)方法添加进去);它将BeanFactoryPostProcessor处理器分成几类来处理,反正最后都要到invokeBeanFactoryPostProcessors方法的。
    private void invokeBeanFactoryPostProcessors(
                Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
            for (BeanFactoryPostProcessor postProcessor : postProcessors) {
                //调用实现类的postProcessBeanFactory方法
                postProcessor.postProcessBeanFactory(beanFactory);
            }
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    到这儿基本结束了,另外文章代码或者我理解有误的地方,希望能批评指出。