06-beanFactoryPostProcessor的执行

2024-05-09 03:28

本文主要是介绍06-beanFactoryPostProcessor的执行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 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接口,所以为trueif (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) {// 如果是BeanDefinitionRegistryPostProcessorif (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.// 用于保存本次要执行的BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类// 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanNameString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// 遍历处理所有符合规则的postProcessorNamesfor (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);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.// 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类// 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,// 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessorpostProcessorNames = 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);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.// 最后,调用所有剩下的BeanDefinitionRegistryPostProcessorsboolean reiterate = true;while (reiterate) {reiterate = false;// 找出所有实现BeanDefinitionRegistryPostProcessor接口的类postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// 遍历执行for (String ppName : postProcessorNames) {// 跳过已经执行过的BeanDefinitionRegistryPostProcessorif (!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);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.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接口的BeanFactoryPostProcessorList<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) {// 跳过已经执行过的BeanFactoryPostProcessorif (processedBeans.contains(ppName)) {// skip - already processed in first phase above}// 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessorselse if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}// 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNameselse 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 {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {System.out.println("执行postProcessBeanDefinitionRegistry---MyBeanDefinitionRegistryPostProcessor");registry.registerBeanDefinition("zzz", new RootBeanDefinition(Teacher.class));}@Overridepublic 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("===============");}@Overridepublic 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;}@Overridepublic 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) {//遍历 postProcessorsfor (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) {//遍历postProcessorsfor (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.*/@Overridepublic 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.*/@Overridepublic 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的beanNameString[] 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);// 存放扫描包下的所有beanSet<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());do {// 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinitionparser.parse(candidates);// 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIBparser.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 classesif (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 {@Overridepublic 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);}@Overrideprotected void initPropertySources() {System.out.println("扩展initPropertySource");getEnvironment().setRequiredProperties("username");}@Overrideprotected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());super.customizeBeanFactory(beanFactory);}@Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {System.out.println("扩展实现postProcessBeanFactory方法");}
}

这篇关于06-beanFactoryPostProcessor的执行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972253

相关文章

如何使用 Bash 脚本中的time命令来统计命令执行时间(中英双语)

《如何使用Bash脚本中的time命令来统计命令执行时间(中英双语)》本文介绍了如何在Bash脚本中使用`time`命令来测量命令执行时间,包括`real`、`user`和`sys`三个时间指标,... 使用 Bash 脚本中的 time 命令来统计命令执行时间在日常的开发和运维过程中,性能监控和优化是不

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

PHP执行php.exe -v命令报错的解决方案

《PHP执行php.exe-v命令报错的解决方案》:本文主要介绍PHP执行php.exe-v命令报错的解决方案,文中通过图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录执行phpandroid.exe -v命令报错解决方案执行php.exe -v命令报错-PHP War

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开发者所认可。本文将记录一下smarty模板引擎的工作执行原理,算是加深一下理解。 其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者

前端-06-eslint9大变样后,如何生成旧版本的.eslintrc.cjs配置文件

目录 问题解决办法 问题 最近在写一个vue3+ts的项目,看了尚硅谷的视频,到了配置eslintrc.cjs的时候我犯了难,因为eslint从9.0之后重大更新,跟以前完全不一样,但是我还是想用和老师一样的eslintrc.cjs文件,该怎么做呢? 视频链接:尚硅谷Vue项目实战硅谷甄选,vue3项目+TypeScript前端项目一套通关 解决办法 首先 eslint 要