首页 > 移动平台 > 详细

Spring 容器 ApplicationContext(五)BeanFactoryPostProcessor

时间:2019-02-23 18:03:37      阅读:235      评论:0      收藏:0      [点我收藏+]

Spring ApplicationContext(五)BeanFactoryPostProcessor

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

本节关注的是第五步:注册 BeanFactoryPostProcessor 并执行。

public void refresh() throws BeansException, IllegalStateException {
    // 5. 注册并执行 BeanFactoryPostProcessor 后置处理器
    invokeBeanFactoryPostProcessors(beanFactory);
}

BeanFactoryPostProcessor 接口如下:

public interface BeanFactoryPostProcessor {
    // All bean definitions will have been loaded, but no beans will have been instantiated yet
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

一、BeanFactoryPostProcessor 应用

1.1 典型应用:PropertyPlaceholderConfigurer

@Value("${age}")
private int age;

xml 配置如下:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:conf.properties</value>
        </list>
    </property>
</bean>

很显然属性注入 beanFactory 是在 beanDefinition 加载完成,即将进行 bean 的加载之前,PropertyPlaceholderConfigurer 实现了 BeanFactoryPostProcessor 接口来完成这一步的工作。

技术分享图片

源代码【PropertyResourceConfigurer】

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    try {
        // 1. 将环境变量和 properties 
        Properties mergedProps = mergeProperties();

        // 2. Convert the merged properties, if necessary.
        convertProperties(mergedProps);

        // 3. 将解析后的属性注册到 Spring 工厂中
        processProperties(beanFactory, mergedProps);
    }
    catch (IOException ex) {
        throw new BeanInitializationException("Could not load properties", ex);
    }
}

1.2 自定义 BeanFactoryPostProcessor

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        int singletonCount = beanFactory.getSingletonCount();
        String[] singletonNames = beanFactory.getSingletonNames();

        System.out.println("BeanFactoryPostProcessor 执行 postProcessBeanFactory() 方法");
        System.out.println("singletonCount:" + singletonCount);
        System.out.println("singletonNames:" + Arrays.asList(singletonNames));
    }
}

运行后结果如下:

BeanFactoryPostProcessor 执行 postProcessBeanFactory() 方法
singletonCount:6
singletonNames:[environment, systemProperties, systemEnvironment, org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry, myBeanFactoryPostProcessor]

二、BeanFactoryPostProcessor 注册及执行

源代码【AbstractApplicationContext】

public void refresh() throws BeansException, IllegalStateException {
    // 5. 注册并执行 BeanFactoryPostProcessor 后置处理器
    invokeBeanFactoryPostProcessors(beanFactory);
}

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

源代码【PostProcessorRegistrationDelegate】

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<String>();

    // 省略 ... 
    // 执行 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry() 方法

    // 1. 筛选出 BeanFactoryPostProcessor 类的类名称,并按 PriorityOrdered、Ordered、nonOrdered 执行
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    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 (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 2. 执行 PriorityOrdered.
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 3. 执行 Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // 4. 执行 nonOrdered
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

private static void invokeBeanFactoryPostProcessors(
        Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

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

Spring 容器 ApplicationContext(五)BeanFactoryPostProcessor

原文:https://www.cnblogs.com/binarylei/p/10423552.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!