06-beanFactoryPostProcessor的执行

news2025/1/13 10:09:04

文章目录

    • invokeBeanFactoryPostProcessors(beanFactory)
    • invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
    • invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    • invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    • ConfigurationClassPostProcessor
    • invokeBeanFactoryPostProcessors(beanFactory);执行流程图
    • 扩展

invokeBeanFactoryPostProcessors(beanFactory)

此方法中是调用各种beanFactory处理器,执行了beanFactoryPostProcessor

	/**
	 * 实例化并且调用所有已经注册了的beanFactoryPostProcessor,遵循指明的顺序
	 *
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值,并且实例化调用执行所有已经注册的beanFactoryPostProcessor
		// 默认情况下,通过getBeanFactoryPostProcessors()来获取已经注册的BFPP,但是默认是空的,那么问题来了,如果你想扩展,怎么进行扩展工作?
		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()));
		}
	}

invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())

这个方法是实例化调用执行所有已经注册的beanFactoryPostProcessor,在这里通过getBeanFactoryPostProcessors()来获取自己定义的beaFacoryPostProcessor

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

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 无论是什么情况,优先执行BeanDefinitionRegistryPostProcessors
        // 将已经执行过的BFPP存储在processedBeans中,防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 判断beanfactory是否是BeanDefinitionRegistry类型,此处是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,所以为true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // 类型转换
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 此处希望大家做一个区分,两个接口是不同的,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子集
            // BeanFactoryPostProcessor主要针对的操作对象是BeanFactory,而BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition
            // 存放BeanFactoryPostProcessor的集合
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 存放BeanDefinitionRegistryPostProcessor的集合
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 首先处理入参中的beanFactoryPostProcessors,遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor
            // 和BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果是BeanDefinitionRegistryPostProcessor
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 添加到registryProcessors,用于后续执行postProcessBeanFactory方法
                    registryProcessors.add(registryProcessor);
                } else {
                    // 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行postProcessBeanFactory方法
                    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
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍历处理所有符合规则的postProcessorNames
            for (String ppName : postProcessorNames) {
                // 检测是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,
            // 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 检测是否实现了Ordered接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后,调用所有剩下的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                // 遍历执行
                for (String ppName : postProcessorNames) {
                    // 跳过已经执行过的BeanDefinitionRegistryPostProcessor
                    if (!processedBeans.contains(ppName)) {
                        // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 按照优先级进行排序操作
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
                registryProcessors.addAll(currentRegistryProcessors);
                // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 执行完毕之后,清空currentRegistryProcessors
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 到这里为止,入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,下面开始处理容器中
        // 所有的BeanFactoryPostProcessor
        // 可能会包含一些实现类,只实现了BeanFactoryPostProcessor,并没有实现BeanDefinitionRegistryPostProcessor接口

        // 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);
        //这里主要处理的是,如果类没有实现BDRPP,直接实现了BFPP,则上面的逻辑不会执行,所以需要在下面补充执行,这种类
        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
//		List<String> orderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> orderedPostProcessor = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName
//		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> nonOrderedPostProcessorNames = new ArrayList<>();
        // 遍历postProcessorNames,将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
        for (String ppName : postProcessorNames) {
            // 跳过已经执行过的BeanFactoryPostProcessor
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNames
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//				orderedPostProcessorNames.add(ppName);
                orderedPostProcessor.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else {
                // 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames
//				nonOrderedPostProcessorNames.add(ppName);
                nonOrderedPostProcessorNames.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合
//		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        // 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合
//		for (String postProcessorName : orderedPostProcessorNames) {
        // 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中
//			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//		}
        // 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作
//		sortPostProcessors(orderedPostProcessors, beanFactory);
        sortPostProcessors(orderedPostProcessor, beanFactory);
        // 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后,创建存放普通的BeanFactoryPostProcessor的集合
//		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        // 遍历存放实现了普通BeanFactoryPostProcessor名字的集合
//		for (String postProcessorName : nonOrderedPostProcessorNames) {
        // 将普通的BeanFactoryPostProcessor添加到集合中
//			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//		}
        // 遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessorNames, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)
        // 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符
        beanFactory.clearMetadataCache();
    }

上面的代码逻辑就是用来调用,实例化调用执行所有已经注册的beanFactoryPostProcessor,首先是先处理外面自定义的beanFactoryPostProcessor,如果此类继承或者实现了BeanDefinitionRegistry类。那么会先转换为BeanDefinitionRegistry,执行此方法postProcessBeanDefinitionRegistry(),然后再依次执行实现PriorityOrdered接口、实现Ordered接口的BeanDefinitionRegistryPostProcessor,最后执行两个都没有实现的BeanDefinitionRegistryPostProcessor,最后在统一执行postProcessBeanFactory()方法。
这里为什么会反复获取BeanDefinitionRegistryPostProcessor呢?
因为在执行postProcessBeanDefinitionRegistry()方法时,可能会有创建新的BeanDefinitionRegistryPostProcessor类,反复执行就可以避免有的BeanDefinitionRegistryPostProcessor类不会被执行。

这里举个栗子


public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("执行postProcessBeanDefinitionRegistry---MyBeanDefinitionRegistryPostProcessor");
        registry.registerBeanDefinition("zzz", new RootBeanDefinition(Teacher.class));
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("执行postProcessBeanFactory---MyBeanDefinitionRegistryPostProcessor");
        BeanDefinition zzz = beanFactory.getBeanDefinition("zzz");
        zzz.getPropertyValues().getPropertyValue("name").setConvertedValue("lisi");
        System.out.println("===============");
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

首先我们自定义了一个BeanDefinitionRegistryPostProcessor,然后我们在postProcessBeanDefinitionRegistry()方法中注册一个BeanDefinition,这样当执行registryProcessor.postProcessBeanDefinitionRegistry(registry);方法时就会创建一个新的BeanDefinition。在下次按照类型获取的时候就会获取到这个新的BeanDefinitionRegistryPostProcessor类

public class Teacher {

    private String name;


    public Teacher() {
        System.out.println("创建teacher对象");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}

在invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())这个方法多次执行了 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);以及invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);这两个方法,后面主要的逻辑也在这两个方法中。

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

    /**
     * 调用给定 BeanDefinitionRegistryPostProcessor Bean对象
     *
     * Invoke the given BeanDefinitionRegistryPostProcessor beans.
     */
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

        //遍历 postProcessors
        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            //调用 postProcessor 的 postProcessBeanDefinitionRegistry以使得postProcess往registry注册BeanDefinition对象
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }

方法中主要遍历执行了postProcessBeanDefinitionRegistry()方法,这里BeanDefinitionRegistryPostProcessor是一个接口,具体postProcessBeanDefinitionRegistry()方法中的逻辑,要看遍历的postProcessor对应的具体实现。

invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

    /**
     * 调用给定的 BeanFactoryPostProcessor类型Bean对象
     *
     * Invoke the given BeanFactoryPostProcessor beans.
     */
    private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

        //遍历postProcessors
        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            //回调 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法,使得每个postProcessor对象都可以对
            // beanFactory进行调整
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

方法中遍历BeanFactoryPostProcessor,执行了postProcessBeanFactory()方法

ConfigurationClassPostProcessor


这里主要看的是这个类,下面的类是自定义的BeanDefinitionRegistryPostProcessor

在ConfigurationClassPostProcessor类中

	/**
	 * 定位、加载、解析、注册相关注解
	 *
	 * Derive further bean definitions from the configuration classes in the registry.
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		// 根据对应的registry对象生成hashcode值,此对象只会操作一次,如果之前处理过则抛出异常
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		// 将马上要进行处理的registry对象的id值放到已经处理的集合对象中
		this.registriesPostProcessed.add(registryId);

		// 处理配置类的bean定义信息
		processConfigBeanDefinitions(registry);
	}

	/**
	 * 添加CGLIB增强处理及ImportAwareBeanPostProcessor后置处理类
	 *
	 * Prepare the Configuration classes for servicing bean requests at runtime
	 * by replacing them with CGLIB-enhanced subclasses.
	 */
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}

		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

上面两个方法就是ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)以及 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),这两个方法都调用了
processConfigBeanDefinitions(registry);方法,用来处理配置类的bean定义信息

/**
	 * 构建和验证一个类是否被@Configuration修饰,并做相关的解析工作
	 *
	 * 如果你对此方法了解清楚了,那么springboot的自动装配原理就清楚了
	 *
	 * Build and validate a configuration model based on the registry of
	 * {@link Configuration} classes.
	 */
	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		// 创建存放BeanDefinitionHolder的对象集合
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		// 当前registry就是DefaultListableBeanFactory,获取所有已经注册的BeanDefinition的beanName
		String[] candidateNames = registry.getBeanDefinitionNames();

		// 遍历所有要处理的beanDefinition的名称,筛选对应的beanDefinition(被注解修饰的)
		for (String beanName : candidateNames) {
			// 获取指定名称的BeanDefinition对象
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			// 如果beanDefinition中的configurationClass属性不等于空,那么意味着已经处理过,输出日志信息
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			// 判断当前BeanDefinition是否是一个配置类,并为BeanDefinition设置属性为lite或者full,此处设置属性值是为了后续进行调用
			// 如果Configuration配置proxyBeanMethods代理为true则为full
			// 如果加了@Bean、@Component、@ComponentScan、@Import、@ImportResource注解,则设置为lite
			// 如果配置类上被@Order注解标注,则设置BeanDefinition的order属性值
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				// 添加到对应的集合对象中
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		// 如果没有发现任何配置类,则直接返回
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		// 如果适用,则按照先前确定的@Order的值排序
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		// 判断当前类型是否是SingletonBeanRegistry类型
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			// 类型的强制转换
			sbr = (SingletonBeanRegistry) registry;
			// 判断是否有自定义的beanName生成器
			if (!this.localBeanNameGeneratorSet) {
				// 获取自定义的beanName生成器
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
						AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
				// 如果有自定义的命名生成策略
 				if (generator != null) {
					//设置组件扫描的beanName生成策略
					this.componentScanBeanNameGenerator = generator;
					// 设置import bean name生成策略
					this.importBeanNameGenerator = generator;
				}
			}
		}

		// 如果环境对象等于空,那么就重新创建新的环境对象
		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		// 实例化ConfigurationClassParser类,并初始化相关的参数,完成配置类的解析工作
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		// 创建两个集合对象,
		// 存放相关的BeanDefinitionHolder对象
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		// 存放扫描包下的所有bean
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			// 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition
			parser.parse(candidates);
			// 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIB
			parser.validate();

			// 获取所有的bean,包括扫描的bean对象,@Import导入的bean对象
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			// 清除掉已经解析处理过的配置类
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			// 判断读取器是否为空,如果为空的话,就创建完全填充好的ConfigurationClass实例的读取器
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			// 核心方法,将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
			this.reader.loadBeanDefinitions(configClasses);
			// 添加到已经处理的集合中
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			// 这里判断registry.getBeanDefinitionCount() > candidateNames.length的目的是为了知道reader.loadBeanDefinitions(configClasses)这一步有没有向BeanDefinitionMap中添加新的BeanDefinition
			// 实际上就是看配置类(例如AppConfig类会向BeanDefinitionMap中添加bean)
			// 如果有,registry.getBeanDefinitionCount()就会大于candidateNames.length
			// 这样就需要再次遍历新加入的BeanDefinition,并判断这些bean是否已经被解析过了,如果未解析,需要重新进行解析
			// 这里的AppConfig类向容器中添加的bean,实际上在parser.parse()这一步已经全部被解析了
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				// 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

invokeBeanFactoryPostProcessors(beanFactory);执行流程图

在这里插入图片描述
上面是refresh() 方法中invokeBeanFactoryPostProcessors(beanFactory);方法的流程详解。

扩展

这里可以自己定制beaFacoryPostProcessor,即扩展自己的beaFacoryPostProcessor
扩展方式:即定义一个类实现BeanFactoryPostProcessor此接口即可。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor执行了------>postProcessBeanFactory");
    }
}

定义此类后,在xml文件中添加或者在自定义的ApplicationContext中添加bean即可
xml文件中:

<bean class="com.zzz.MyBeanFactoryPostProcessor"></bean>

在ApplicationContext注入,这里使用的xml的方式,所以需要继承ClassPathXmlApplicationContext

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {


    public MyClassPathXmlApplicationContext(String... configLocations){
        super(configLocations);
    }

    @Override
    protected void initPropertySources() {
        System.out.println("扩展initPropertySource");
        getEnvironment().setRequiredProperties("username");
    }

    @Override
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
        super.customizeBeanFactory(beanFactory);
    }

    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        System.out.println("扩展实现postProcessBeanFactory方法");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1654170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker desktop实战部署oracle篇

1、前言 oracle数据库官方已提供现成的镜像&#xff0c;可以直接拿来部署了。 由于项目中需要使用oracle数据库的分表功能&#xff0c;之前安装的是standard版本&#xff0c;无奈只能重新安装。网上查了一番&#xff0c;使用的方法都比较传统老旧&#xff1a;下载安装包手动安…

Ps中 饱和度 和 自然饱和度 的区别?

1.饱和度&#xff08;Saturation&#xff09;&#xff1a;在Photoshop中&#xff0c;饱和度是一个全局性调整&#xff0c;它影响图像中所有颜色的鲜艳程度。当你增加饱和度时&#xff0c;所有的颜色都会变得更浓烈、更鲜艳&#xff1b;相反&#xff0c;减小饱和度会使图像整体变…

解决 git克隆拉取代码报SSL certificate problem错误

问题&#xff1a;拉取代码时报错&#xff0c;SSL证书问题:证书链中的自签名证书问题 解决&#xff1a;只需要关闭证书验证&#xff0c;执行下面代码即可&#xff1a; git config --global http.sslVerify "false" 再次拉取代码就可以了

怎样选择IT外包公司?需要注意什么?

随着网络化、数字化、智能化快速发展&#xff0c;一部分企业成立自己的IT部门&#xff0c;负责各个科室的网络安全&#xff0c;大部分企业把网络安全、数据安全&#xff0c;外包给专业的IT外包公司&#xff0c;既提升了办公效率&#xff0c;企业又能把主要精力放在发展核心业务…

(二刷)代码随想录第1天|704. 二分查找 27. 移除元素

704. 二分查找 704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode&#xff1a;704. 二分查找_哔哩哔哩_bilibili 给定一个 n 个元素有序的&#xff08;升序&#xff09…

Unity如何使用adb工具安装APK

1、下载adb工具 SDK 平台工具版本说明 | Android Studio | Android Developers (google.cn) 2、配置环境变量 把platform-tools的路径添加进去就行 打开cmd&#xff0c;输入adb&#xff0c;即可查看版本信息 3、使用数据线连接设备&#xff0c;查看设备信息&#xff08;…

后教培时代的新东方,正在找寻更大的教育驱动力?

近段时间&#xff0c;K12教育主要上市公司的阶段性业绩皆已出炉。从具体数据来看&#xff0c;随着时间推移&#xff0c;教培机构的转型之路已愈走愈顺。 财报显示&#xff0c;2023年12月1日-2024年2月29日&#xff0c;好未来实现营收4.3亿美元&#xff0c;同比增长59.7%&#…

C++ | Leetcode C++题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; class Solution { public:string getPermutation(int n, int k) {vector<int> factorial(n);factorial[0] 1;for (int i 1; i < n; i) {factorial[i] factorial[i - 1] * i;}--k;string ans;vector<int> valid(n 1, 1);…

小程序支付的款项流转与到账时间

商家做小程序&#xff0c;最关心的是客户通过小程序下单支付的钱&#xff0c;是怎么样的流转状态以及最终到哪里。因此&#xff0c;本文将详细解析款项最终流向何处以及多久能够到账。 一、小程序支付的款项流向 当用户在小程序内完成支付后&#xff0c;款项并不会直接到达商…

数据结构学习——线性表、顺序表

1.线性表 线性表 &#xff08; linear list &#xff09; 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一…

多线程【阻塞队列】(生产者消费者模型代码实现)

阻塞队列 解耦合削峰填谷生产者消费者模型&#xff1a; 解耦合 削峰填谷 生产者消费者模型&#xff1a; 正常来说&#xff0c;wait通过notify唤醒&#xff0c;其他线程调用了take,在take的最后一步进行notify. package thread; class MyBlockingQueue{private String [] data…

jmeter控制器讲解

1&#xff0c;随机顺序控制器和随机控制器的区别&#xff1a;随机顺序控制器下所有的接口都会执行&#xff0c;只是执行顺序是随机的&#xff0c;随机控制器下所有的接口中随机执行一个接口&#xff0c;其余接口不执行。

idea 项目 修改项目文件名 教程

文章目录 目录 文章目录 修改流程 小结 概要流程技术细节小结 概要 原项目名 修改流程 关掉当前项目的idea页面 修改之后的文件名 重新打开idea。选择项目打开项目页面 技术细节 出现下面这个问题&#xff0c;可以参考作者新的一编文章idea开发工具 项目使用Spring框架开发解…

【iOS】-- 内存五大分区

【iOS】-- 内存五大分区 内存五大分区1.栈区优点&#xff1a; 2.堆区优点&#xff1a; 3.全局区4.常量区5.代码区 验证static、extern、const关键字比较1.static关键字static关键字的作用&#xff1a;全局静态变量局部静态变量 2.extern关键字对内的全局变量对外的全局变量 3.c…

[报错解决]SpringBoot子项目打jar包启动报 XXX--1.0-SNAPSHOT.jar中没有主清单属性

目录 报错信息解决原因原因分析解决方案 报错信息 解决 原因 在使用SpringBoot架构搭建父子工程时&#xff0c;使用IDEA可以正常启动&#xff0c;对子项目打成jar包后使用jar方式启动时&#xff0c;会报错xx.jar中没有主清单属性。 原因分析 原因主要是在使用jar方式启动时…

2024年第六届世界软件工程研讨会(WSSE 2024)即将召开!

2024年第六届世界软件工程研讨会&#xff08;WSSE 2024&#xff09;将于2024年9月13-15日在日本京都举行。软件工程领域的发展离不开各位专家学者和业界精英的共同努力和贡献。WSSE 2024将就软件工程领域的最新研究成果、实践经验和发展趋势进行深入交流和探讨&#xff0c;汇聚…

VxTerm使用教程:连接SSH服务端设备,什么是SSH

一、什么是SSH&#xff1f; <摘自百度> 安全外壳协议 SSH&#xff0c;即安全外壳协议&#xff08;Secure Shell&#xff09;&#xff0c;是一种网络协议&#xff0c;用于在计算机网络上提供安全的远程登录和命令执行功能。 SSH通过加密通信通道来保护数据传输&#xff0c…

企业车辆管理系统参考论文(论文 + 源码)

【免费】关于企业车辆管理系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89282550 企业车辆管理系统 摘 要 随着经济的日益增长,车辆作为最重要的交通工具,在企事业单位中得以普及,单位的车辆数目已经远远不止简单的几辆,与此同时就产生了车辆资源的合理…

Django-新冠疫情数据分析系统-67684

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 新冠疫情数据分析系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析…

Nacos单机模式集成MySQL

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nacos支持三种部署…