Spring处理@Configuration的分析

@Configuration注解在SpringBoot中作用很大,且不说SpringBoot中的外部化配置,一些第三方组件也是通过这个注解完成整合的,常用的比如说mybatis,就是利用了@Configuration这个注解来实现的。

在注解类中,还可以使用@Bean的方式向Spring容器中,注入一些我们自定义的组件。

在SpringBoot中各种Enable又是如何实现的?和@Configuration又有什么联系呢?

这就要了解Spring是怎么对待被@Configuration所注解的类。

环境

SpringBoot 2.2.6RELEASE

Spring 5.2.5.RELEASE

正文

注解依附于具体的Java类,所以如果想获取注解的信息,必须先将类加载进来,才能从Class对象获取到其注解元信息。

好在Spring容器启动之前,已经把所有需要加载的Bean,封装成一个BeanDefinition对象,最终注册到BeanDefinitionRegistry中。

BeanDefinition包含了一个Bean所有的信息,自然也包含了它的元注解信息。

有了这个就能轻而易举的获取到标注有@Configuration注解的BeanDefinition,从而去处理这个配置类拥有的各种配置信息。

有了BeanDefinition之后,下面一步就是要进行Bean的实例化了。如果一个Bean被实例化后,就没有可操作的机会了,因此Spring在Bean的实例化前预留了一些自定义的处理时机。

BeanFactoryPostProcessor就是这样的一个功能,用于在Bean实例化之前,做一些其他的处理操作。

对配置类的处理,也正是利用了这一预留点。

BeanDefinitionRegistryPostProcessor

处理配置类,第一步就要从茫茫的BeanDefinition中,找出哪些是配置类。

容器开始启动之前的一些准备动作,这里不说明,主要是扫描classpath,然后将生成BeanDefinition。

直接从容器的启动开始简单下调用栈

Spring容器真正开始启动的是从这里开始的org.springframework.context.support.AbstractApplicationContext#refresh,在这个方法中,会去执行所有的BeanFactoryPostProcessor。

通过一个委托类org.springframework.context.support.PostProcessorRegistrationDelegate,执行所有的BeanFactoryPostProcessor后置处理逻辑。

BeanFactoryPostProcessor有一个子接口是BeanDefinitionRegistryPostProcessor,这个接口的主要作用就是在其他后置处理执行之前,额外注册一些BeanDefinition进来。

想想在配置类中使用的@Import和@Bean,就可以猜到,这些注解的处理就是由这个处理器进行处理的。

BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor是放到一起处理的,只不过BeanDefinitionRegistryPostProcessor的执行时机,早于BeanFactoryPostProcessor的执行时机。

// org.springframework.context.support.PostProcessorRegistrationDelegate public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); // 如果BeanFactory同时又是一个BeanDefinitionRegistry的话 // 例如 DefaultListaleBeanFactory if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 如果有直接注册到Context的后置处理器, // 先执行直接添加到ApplicationContext的BeanDefinitionRegistryPostProcessor处理器 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 执行BeanDefinitionRegistryPostProcessor处理器 registryProcessor.postProcessBeanDefinitionRegistry(registry); // BeanDefinitionRegistryPostProcessor同时又是一个BeanFactoryPostProcessor // 待所有的BeanDefinitionRegistryPostProcessor执行完后,再来执行它 registryProcessors.add(registryProcessor); } else { // 加入到BeanFactoryPostProcessor处理器集合中,待所有的BeanDefinitionRegistryPostProcessor执行完后,来执行它 regularPostProcessors.add(postProcessor); } } List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 对从BeanDefinitionRegistry中的BeanDefinition做后置处理 // 先执行被@PriorityOrdered注解的BeanDefinitionRegistryPostProcessor // 并且按排序大小进行优先级排序 // 根据类型,从BeanDefinitionRegistry中查找出所有的BeanDefinitionRegistryPostProcessor的是实现类,及子类 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 使用@PriorityOrdered注解的先查找出来 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 按编号大小排序,升序排列 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 执行BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 处理被注解@Ordered标注的BeanDefinitionRegistryPostProcessor, // 并且按排序后排序后执行 // 根据类型,从BeanDefinitionRegistry中查找出所有的BeanDefinitionRegistryPostProcessor的是实现类,及子类 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 没被处理过且被注解@Ordered if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 执行BeanDefinitionRegistryPostProcessor invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // 再去执行其他的剩下的所有BeanDefinitionRegistryPostProcessor boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // BeanDefinitionRegistryPostProcessor也是一个BeanFactoryPostProcessor // 下面这部分就是执行postProcessBeanFactory方法, // 会在@Configuration的proxyBeanMethods为true时对配置类做一个CGLIB增强, // 表示对配置类中的BeanMethod创建时,使用代理创建 // 将增强后的类,替换到其BeanDefinition#setBeanClass invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 最后再执行直接注册到到ApplicationContext中的BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // 处理直接通过ApplicationContext实例注册的BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 上面就执行过了定义的所有的BeanDefinitionRegistryPostProcessor,以及实现的 // BeanFactoryPostProcessor#postProcessBeanFactory方法 // 接下来回去执行所有的BeanFactoryPostProcessor处理器 // 查找出所有注册的类型为BeanFactoryPostProcessor的BeanDefinition的name数组 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // 分别归类出使用@PriorityOrdered 和 @Ordered注解和没有使用的 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // 处理过的,不用重复处理 } 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); } } // 优先处理 PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 其次 Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); //最后普通的 BeanFactoryPostProcessor List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); beanFactory.clearMetadataCache(); }

上面这个方法执行完后,已经完成了所有BeanFactoryPostProcessor的执行,也自然已经处理过所有的配置类了。

ConfigurationClassPostProcessor

在众多的后置处理器中,有一个独属于@Configuration的后置处理器,就是ConfigurationClassPostProcessor,一个好的命名的效果,就体现出来了。

下面这个方法,负责两件事

从BeanDefinitionRegistry中筛选出配置类

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxzpx.html