接口简介
BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
注意点:通过BeanDefinitionRegistryPostProcessor 注册的 BeanDefinitionRegistryPostProcessor 接口的postProcessBeanDefinitionRegistry方法将得不到调用,具体的原因会在下面的代码中解释。
BeanFactoryPostProcessor 接口调用机制
BeanFactoryPostProcessor 接口的调用在 AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 用于存放已经处理过的Bean名字 Set<String> processedBeans = new HashSet<>(); // 一般会进入这个判断 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 所谓的regularPostProcessors就是指实现BeanFactoryPostProcessor接口的Bean List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 所谓的registryProcessors就是指实现BeanDefinitionRegistryPostProcessor接口的Bean List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 这边遍历的是通过ApplicationContext接口注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口 // 需要和BeanFactory中BeanDefinitionMap中的BeanFactoryPostProcessor接口区分开 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; //如果是BeanDefinitionRegistryPostProcessor,则先进行postProcessBeanDefinitionRegistry处理,这个方法一般进行BeanDefinition注册,从这边可以看出BeanDefinitionRegistryPostProcessor接口的方法先调用,所以优先级高于BeanFactoryPostProcessor // 通过这个代码可以看出,通过ApplicationContext直接注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor并不支持Order接口,而是根据注册的顺序执行 registryProcessor.postProcessBeanDefinitionRegistry(registry); // 保存这个BeanDefinitionRegistryPostProcessor,因为还要执行这个类的BeanFactoryPostProcessor方法; registryProcessors.add(registryProcessor); } else { // 保存,后面还要执行这个类的BeanFactoryPostProcessor方法; regularPostProcessors.add(postProcessor); } } List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 这边获取的是BeanFactory中的BeanDefinitionRegistryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //先处理PriorityOrdered标注的BeanDefinitionRegistryPostProcessor if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //将其标记为已经处理,防止重复处理 processedBeans.add(ppName); } } // 将其排序,以便按顺序处理 sortPostProcessors(currentRegistryProcessors, beanFactory); // 将其保存,以便处理这个类的BeanFactoryPostProcessor方法 registryProcessors.addAll(currentRegistryProcessors); // 执行BeanDefinitionRegistryPostProcessor接口方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清除,以便开始处理@Order标注的注解 currentRegistryProcessors.clear(); // 注意:这边重新获取BeanDefinitionRegistryPostProcessor是有深意的,因为上面在处理@PriorityOrdered标注的BeanDefinitionRegistryPostProcessor时可能又注入了新的BeanDefinitionRegistryPostProcessor。 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 判断是否处理过,防止重复处理,下面的逻辑和上面相同, 不介绍了 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcesso.........