BeanFactoryPostProcessor详解

一、简介

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

二、使用

  • spring-base.xml配置



<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"


     >



  
    <bean id ="myTestBean" class= "com.zzq.core.test.entity.MyTestBean" >

    bean>


      <bean id ="customBeanFactoryPostProcessor" class= "com.zzq.core.test.processor.CustomBeanFactoryPostProcessor" >bean>

    
beans>
  • 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");


    }

}
  • 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;
    }



}
  • 运行的主函数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());

    }

}
  • 运行结果,对象的name属性已被更改。
    BeanFactoryPostProcessor详解_第1张图片

三、查看源码

  • 从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;
            }
        }
    }
  • 省略了部分代码,我们此次要关注的就是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 regularPostProcessors = new LinkedList();
            List registryPostProcessors =
                    new LinkedList();
            //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 registryPostProcessorBeans =
                    new ArrayList(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 priorityOrderedPostProcessors = new ArrayList();
        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 orderedPostProcessors = new ArrayList();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        OrderComparator.sort(orderedPostProcessors);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        //最后,调用所有其他后处理器。
        List nonOrderedPostProcessors = new ArrayList();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    }
  • 一般情况下不会走到for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {里面,getBeanFactoryPostProcessors()元素为空(如果一定要让它走这儿的话,可以自己继承ClassPathXmlApplicationContext,重写里面的postProcessBeanFactory方法,使用addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)方法添加进去);它将BeanFactoryPostProcessor处理器分成几类来处理,反正最后都要到invokeBeanFactoryPostProcessors方法的。
private void invokeBeanFactoryPostProcessors(
            Collection postProcessors, ConfigurableListableBeanFactory beanFactory) {

        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            //调用实现类的postProcessBeanFactory方法
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

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

你可能感兴趣的:(java,spring,Spring入门及源码分析)