spring的启动过程03-bean工厂后置处理器
2016-12-28 16:02
344 查看
概述:
在spring的启动过程中,bean工厂创建成功并加载所有的XML资源文件生成BeanDefinitions集合后,实例化所有singlelonBean对象之前,需要对beanDefinition做额外的操作,bean工厂后置处理器就发挥重要作用了。
一个经常用到的场景:业务代码中或者XML文件中配置bean属性的值经常采用${...}占位符,把参数写入properties文件中,xml中只需配置如下bean,spring就会完成占位符的替换。
首先看下PropertyResourceConfigurer类静态结构图
![](https://img-blog.csdn.net/20161229093610046?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjg1ODA5NTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
可以发现该类实现了BeanFactoryPostProcessor、PriorityOrdered接口,下面我们看下实现这两个接口的bean在spring容器启动过程中何时被触发
org.springframework.context.support.AbstractApplicationContext启动Spring容器核心类
官方的解释是:在实例化所有bean之前,可以添加额外的bean definition。
下面看下spring启动过程中常用的后置处理器有哪些:
1. org.springframework.context.annotation.ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口
(该类主要处理通过注解的bean实例,后续会有通过注解定义bean的原理文章具体讲解)
2. org.mybatis.spring.mapper.MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口
(该类主要实现了mybatis扫描DAO接口转换为beanDefinition的过程,后续会有mybatis与spring集成原理文章具体讲解)
3.org.springframework.beans.factory.config.PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口
(该类主要加载指定的properties文件并替换${...}占位符,后续会有替换占位符原理文章具体讲解)
总结:
这篇文件主要说明了bean工厂后置处理器的作用及实现方式,spring容器利用这个功能做了大量的个性化集成如与mybatis的集成,后续文章会把常用的工厂处理器拿出来具体分析。刚开发了分布式配置中心系统,参数的动态植入就是利用了spring的bean工厂后置处理器原理。spring源码解析的文章网上比比皆是,每个作者的出发点不同故而讲解的重点也会不同,打算从个人的出发点并吸取别人的优点写一系列spring源码解析文章。欢迎各位拍砖,有问题请留言一起探讨一起成长。
在spring的启动过程中,bean工厂创建成功并加载所有的XML资源文件生成BeanDefinitions集合后,实例化所有singlelonBean对象之前,需要对beanDefinition做额外的操作,bean工厂后置处理器就发挥重要作用了。
一个经常用到的场景:业务代码中或者XML文件中配置bean属性的值经常采用${...}占位符,把参数写入properties文件中,xml中只需配置如下bean,spring就会完成占位符的替换。
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:${profile.properties}/*.properties</value> </list> </property> </bean>原理:
首先看下PropertyResourceConfigurer类静态结构图
可以发现该类实现了BeanFactoryPostProcessor、PriorityOrdered接口,下面我们看下实现这两个接口的bean在spring容器启动过程中何时被触发
org.springframework.context.support.AbstractApplicationContext启动Spring容器核心类
public void refresh() throws BeansException, IllegalStateException { ... // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); ... }在refresh方法中创建完Bean工厂并加载完BeanDefinition实例后,触发bean工厂后置处理器
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * 实例化并调用所有注册的BeanFactoryPostProcessor实例 * respecting explicit order if given. * <p>Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); }下面我们重点看下静态方法invokeBeanFactoryPostProcessors的实现逻辑
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 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>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. // BeanDefinitionRegistryPostProcessor核心接口,从bean工厂获取实现了BeanDefinitionRegistryPostProcessor接口的beanDefinition集合 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProc aa3b essor>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registryPostProcessors.addAll(priorityOrderedPostProcessors); // 触发接口方法 invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, orderedPostProcessors); registryPostProcessors.addAll(orderedPostProcessors); // 触发接口方法 invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); registryPostProcessors.add(pp); processedBeans.add(ppName); // 触发接口方法 pp.postProcessBeanDefinitionRegistry(registry); reiterate = true; } } } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, 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核心接口,从bean工厂获取实现了BeanFactoryPostProcessor接口的beanDefinition集合 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. 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); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(beanFactory, priorityOrderedPostProcessors); // 触发接口方法 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(beanFactory, orderedPostProcessors); // 触发接口方法 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. 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(); }下面看下核心接口的方法定义
public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }官方的解释是:bean工厂创建所有的bean definitions之后,但是没有bean实例化之前,可以覆盖或者增加参数到急需初始化的bean。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
官方的解释是:在实例化所有bean之前,可以添加额外的bean definition。
下面看下spring启动过程中常用的后置处理器有哪些:
1. org.springframework.context.annotation.ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口
(该类主要处理通过注解的bean实例,后续会有通过注解定义bean的原理文章具体讲解)
2. org.mybatis.spring.mapper.MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口
(该类主要实现了mybatis扫描DAO接口转换为beanDefinition的过程,后续会有mybatis与spring集成原理文章具体讲解)
3.org.springframework.beans.factory.config.PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口
(该类主要加载指定的properties文件并替换${...}占位符,后续会有替换占位符原理文章具体讲解)
总结:
这篇文件主要说明了bean工厂后置处理器的作用及实现方式,spring容器利用这个功能做了大量的个性化集成如与mybatis的集成,后续文章会把常用的工厂处理器拿出来具体分析。刚开发了分布式配置中心系统,参数的动态植入就是利用了spring的bean工厂后置处理器原理。spring源码解析的文章网上比比皆是,每个作者的出发点不同故而讲解的重点也会不同,打算从个人的出发点并吸取别人的优点写一系列spring源码解析文章。欢迎各位拍砖,有问题请留言一起探讨一起成长。
相关文章推荐
- Spring Boot学习笔记03--深入了解SpringBoot的启动过程
- 《Spring技术内幕》学习笔记10——Web环境中Spring的启动过程
- 如何插手spring启动过程
- 杂(关于spring容器启动时加载过程的探索)
- 《Spring技术内幕》学习笔记10——Web环境中Spring的启动过程
- spring启动component-scan类扫描加载过程---源码分析
- 剖析Linux系统启动过程 - chenchao03的专栏 - CSDNBlog
- spring容器启动的加载过程(一)
- spring启动component-scan类扫描加载过程---源码分析
- Spring-IOC+DI-启动过程
- Web环境中Spring的启动过程
- spring启动过程之源码跟踪(上)--spring Debug
- spring—容器启动载入bean过程
- spring启动component-scan类扫描加载过程---源码分析
- spring启动component-scan类扫描加载过程---源码分析
- Spring容器启动过程
- spring启动过程之源码跟踪(续beanfactory)--spring Debug
- spring启动过程之源码跟踪(上)--spring Debug
- spring技术内幕10-Web环境中Spring启动过程
- spring启动component-scan类扫描加载过程---源码分析