SPRING08_后置处理器三大接口、BeanDefinitionRegistryPostProcessor处理器、BeanFactoryPostProcessor处理器、处理器应用

①. 后置处理器的接口关系

  • ①. 前面研究了BeanPostProcessorbean的后置处理器,实际上在Spring的底层还有一个东西BeanFactoryPostProcessorbean工厂的后置处理器

  • ②. BeanPostProcessor和BeanFactoryPostProcessor从起名上的区别:它们最后都叫PostProcessor,然后按照这个翻译都具有后置增强的功能,但是都后置增强的什么功能

  • ③. BeanPostProcessor是后置增强了普通的bean组件。BeanFactoryPostProcessor这是后置增强bean工厂的,这相当于增强用的档案馆大工厂和单实例池
    在这里插入图片描述

  • ④. 在Spring底层围绕着整个生命周期,它会有非常复杂麻烦的运行逻辑。首先有一个叫BeanFactoryPostProcessorbean工厂的后置处理器,在BeanFactoryPostProcessorbean工厂的后置处理器下面有两个接口,一个是它自身BeanFactoryPostProcessor,一个BeanDefinitionRegistryPostProcessor

// 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;

}

在这里插入图片描述

  • ⑤. InitializingBean接口初始化bean, InitializingBean接口里面还有一个方法叫afterPropertiesSet(), InitializingBean接口初始化bean里面没有啥子接口,只有它自己这个大接口InitializingBean
// Bean组件初始化以后对组件进行后续的设置,在于额外处理
public interface InitializingBean {
	/**
	 * Invoked by the containing {@code BeanFactory} after it has set all bean properties
	 * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
	 * <p>This method allows the bean instance to perform validation of its overall
	 * configuration and final initialization when all bean properties have been set.
	 * @throws Exception in the event of misconfiguration (such as failure to set an
	 * essential property) or if initialization fails for any other reason
	 */
	void afterPropertiesSet() throws Exception;
}

②. 三个接口的主要特点

  • ①. BeanFactoryPostProcessor:对bean工厂进行后置增强,这是一个工厂的后置处理器,但结果它给接口暴露的方法是postProcessBeanFactory后置增强bean工厂这个方法,并直接把BeanFactory(bean工厂)传了进来,也就是传入进来bean工厂,那就能想做什么就做什么。而注册组件只是最简单的事情,所以直接把BeanFactory(bean工厂)传了进来,可以在这个BeanFactory(bean工厂)定义父子工厂,包括BeanFactory(bean工厂)里面来进行实例隔离,甚至于自定义一个池,准备一些隔离组件,但似乎目前市面上从没有见过这种用法,因为用不到这么深,但是它却留了这么一个接口方法叫postProcessBeanFactory后置增强bean工厂
@FunctionalInterface
public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
  • ②. BeanPostProcessor:最大的接口,这叫后置增强组件,在这个BeanPostProcessor接口下面有非常多的子接口,只要研究清楚每一个子接口的增强器在何时运行,BeanPostProcessor它不是只有一个运行时机,这是因为BeanPostProcessor它不止有一个运行时机
// 对BeanFactory进行后置的增强。我们要弄清楚每一个子接口的增强器在何时运行;在于改变
public interface BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}
  • ③. InitializingBean:初始化Bean组件,这个是在Bean组件初始化以后对组件进行的后续设置,它跟后置处理器BeanPostProcessor不一样的是,InitializingBean的接口是空参的,而后置处理器BeanPostProcessor会传一些当前正在哪个环节的上下文环境的相关信息,所以能对这些信息进行修改,也就是InitializingBean跟后置处理器BeanPostProcessor这两个的区别
  1. 后置处理器BeanPostProcessor能够传入一些东西,比如:Object bean, String beanName 这些东西可以进行一个改变,后置处理器在于改变,比如@Autowired的后置处理器,它就在于改变自动装配的属性值的赋值过程
  2. InitializingBean其实也是在组件的初始化以后做的事情,但是之前BeanPostProcessor它也是在组件创建好对象初始化前后做的事情,这BeanPostProcessor和InitializingBean这两个虽然都在相关组件干完活之后才干的事,但是InitializingBean是在于额外处理的,因为它不会传入当前组件的任何信息,所以在这一阶段可以进行额外的处理
    (比如当前是一个线程池,线程池初始化完了以后,调用InitializingBean接口下面的afterPropertiesSet,就是整个线程池对象准备好以后,可以把线程池里面的指标信息通过可视化界面暴露出来,这也就是一个功能上的一个增强,而不在于改变)
// Bean组件初始化以后对组件进行后续的设置,在于额外处理
public interface InitializingBean {
	void afterPropertiesSet() throws Exception;
}

③. 测试坏境搭建三种类

  • ①. 无论是改变还是额外处理都是增强的机制,但是它们之间却有着天壤之别,为了方便期间,提前准备好了所有后置增强机制以及初始化Bean组件的类
    在这里插入图片描述

  • ②. bean包下面的组件
    在这里插入图片描述在这里插入图片描述

package com.xiaozhi.processor.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 自定义Bean组件的 PostProcessor;
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
	public MyBeanPostProcessor(){
		System.out.println("MyBeanPostProcessor...");
	}
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyBeanPostProcessor...postProcessAfterInitialization..."+bean+"==>"+beanName);
		return bean;
	}
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyBeanPostProcessor...postProcessBeforeInitialization..."+bean+"==>"+beanName);
		return bean;
	}
}
package com.xiaozhi.processor.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
	public MyInstantiationAwareBeanPostProcessor(){
		System.out.println("MyInstantiationAwareBeanPostProcessor...");
	}
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessBeforeInstantiation=>"+beanClass+"--"+beanName);
		return null;
	}
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessAfterInstantiation=>"+bean+"--"+beanName);
		return true;
	}
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessProperties=>"+bean+"--"+beanName);
		return null;
	}
//	public PropertyValues postProcessPropertyValues(
//			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
//		System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessProperties");
//		return pvs;
//	}
}
package com.xiaozhi.processor.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

	public MyMergedBeanDefinitionPostProcessor(){
		System.out.println("MyMergedBeanDefinitionPostProcessor...");
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessBeforeInitialization...=>"+bean+"--"+beanName);
		return null;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessAfterInitialization..=>"+bean+"--"+beanName);
		return null;
	}

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		System.out.println("MyMergedBeanDefinitionPostProcessor...postProcessMergedBeanDefinition..=>"+beanName+"--"+beanType+"---"+beanDefinition);
	}

	@Override
	public void resetBeanDefinition(String beanName) {
		System.out.println("MyMergedBeanDefinitionPostProcessor...resetBeanDefinition.."+beanName);

	}
}
package com.xiaozhi.processor.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Constructor;

@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {

	public MySmartInstantiationAwareBeanPostProcessor() {
		System.out.println("MySmartInstantiationAwareBeanPostProcessor...");
	}

	public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("MySmartInstantiationAwareBeanPostProcessor...predictBeanType=>" + beanClass + "--" + beanName);
		return null;
	}

	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)

			throws BeansException {
		System.out.println("MySmartInstantiationAwareBeanPostProcessor...determineCandidateConstructors=>" + beanClass + "--" + beanName);

		return null;
	}

	public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		System.out.println("MySmartInstantiationAwareBeanPostProcessor...getEarlyBeanReference=>" + bean + "--" + beanName);

		return bean;
	}
}
  • ③. factory包下面类
package com.xiaozhi.processor.factory;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;

/**
 * BeanFactory的后置处理器  , PriorityOrdered, Ordered
 */
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
	public MyBeanDefinitionRegistryPostProcessor() {
		System.out.println("MyBeanDefinitionRegistryPostProcessor");
	}

	@Override  //紧接着执行
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanDefinitionRegistryPostProcessor....postProcessBeanFactory...");
	}

	@Override  //先执行的
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanDefinitionRegistry...");
		//增强bean定义信息的注册中心,比如自己注册组件
	}
}
package com.xiaozhi.processor.factory;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * BeanFactory的后置处理器
 */
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	public MyBeanFactoryPostProcessor() {
		System.out.println("MyBeanFactoryPostProcessor...");
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("BeanFactoryPostProcessor....postProcessBeanFactory==>" + beanFactory);
	}
}
  • ④. InitializingBean包下面类
package com.xiaozhi.processor.InitializingBean;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * 生命周期接口
 */
@Component
public class MyInitializingBean implements InitializingBean {

	public MyInitializingBean(){
		System.out.println("MyInitializingBean....");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("MyInitializingBean...afterPropertiesSet...");
	}
}
  • ⑤. 理清一个bean生命周期的流程图,bean的创建很简单,就是为了创建出一个对象,但是在bean的创建整个期间,这个对象创建好那么前后会有非常多的增强器机制来进行干预运行,一干预以后创建的bean对象有可能也就不对了,包括bean对象创建完以后可能都不是原来只有基础简单的几个功能了,所以整个bean对象的创建期间前边的这个后置处理,后边的后置处理器会围绕整个bean的创建过程来做一个增强机制,整个后置处理器围绕着整个bean的创建和初始化过程对bean功能进行改造

  • ⑥. Spring以后各种强大功能,只要有这些后置处理器把普通组件进行改造那么就是一个增强后的机制,接下来就要看bean创建期间的前后到底哪些后置处理器干了哪些工作,只要再把这个搞清楚,那么接下来无论是对Spring里面底层原理的理解还是我们自定义组件都大有帮助

④. BeanDefinitionRegistryPostProcessor后置处理器执行

背景:什么时候会去执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法?我们在MyBeanDefinitionRegistryPostProcessor类的如下位置打上断点。新建一个Bean2.xml,使用xml方式进行启动容器

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
	<bean class="com.xiaozhi.bean.Cat2" id="cat2">
		<property name="name" value="TOMCAT"></property>
	</bean>
	<context:component-scan base-package="com.xiaozhi.processor"/>
</beans>

在这里插入图片描述

  • ①. IOC容器一启动,就准备创建IOC容器的这个对象
    结果是:进入第一个后置处理器就是BeanDefinitionRegistryPostProcessorbean定义信息注册中心的后置增强 ,这个第一个后置处理器是准备创建对象,Cat2这个相应对象还没开始创建,但是先上来第一后置处理器就来了–BeanDefinitionRegistryPostProcessor,它是先进行创建出对象。它是如何创建对象,debug源码进行分析

  • ②. 分析结果:调用三参构造、刷新容器

  1. 创建一个IOC容器,调用三参数的构造器方法,准备刷新容器,然后容器刷新里面有一个关键环节叫invokeBeanFactoryPostProcessors执行bean工厂的后置增强器,而invokeBeanFactoryPostProcessors这个的下面才是初始化所有单实例beanfinishBeanFactoryInitialization(beanFactory),还没走到下边,当前这个对象创建还在最下边,但debug的时候都还没走到对象初始化这一块,所以在最前边就会执行所有的BeanFactory后置增强
  2. 增强Bean工厂是因为上一步都已经把bean工厂按照xml创建好了 – ConfigurableListableBeanFactory
  3. 想在这个bean工厂准备创建其他bean之前,如果想要对创建好的工厂bean来做一些工作,就可以在这一块invokeBeanFactoryPostProcessors执行bean工厂的后置增强器)进行,可以利用BeanFactoryPostProcessorsbean工厂的后置增强器)对工厂进行一些修改或者增强等操作
//[1]. 准备创建一个IOC容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("xxx.xml");

//[2]. 调用IOC容器那三参数的构造器方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	this(new String[] {configLocation}, true, null);
}

//[3]. 准备刷新容器
if (refresh) {
	refresh(); //刷新容器
}
//[4]. 执行所有的BeanFactory后置增强
// 工厂增强:执行所有的BeanFactory后置增强器,利用BeanFactory对工厂进行增强或修改
// 解释下:在finishBeanFactoryInitialization方法之前执行增强逻辑,可以在bean没有创建的时候,就对bean对象进行增强处理
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

在这里插入图片描述

  • ③. invokeBeanFactoryPostProcessors执行bean工厂的后置增强器环节,在这个环节的时候就开始创建了一个后置增强处理器
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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}
  • ④. 执行invokeBeanFactoryPostProcessors具体的流程
  1. 首先,从工厂中获取所有的BeanDefinitionRegistryPostProcessor(我们写的bean里面有定义),是不是实现了PriorityOrdered接口。如果有排序,排序后进行执行方法
  2. 接下来获取所有获取Ordered接口的BeanDefinitionRegistryPostProcessor,如果有排序,排序后进行执行方法
  3. 最后我们自定义没有任何优先级和排序接口(实现了BeanDefinitionRegistryPostProcessor)
public static void  invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {

			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// [1]. 首先,从工厂中获取所有的BeanDefinitionRegistryPostProcessor(我们写的bean里面有定义)。 First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 从工厂中看是不是实现了PriorityOrdered接口(PriorityOrdered是顺序接口,数字越小,优先级越高)
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));// 如果有,放入前面定义好的集合currentRegistryProcessors
					processedBeans.add(ppName);
				}
			}
			// 按照顺序排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行这些BeanDefinitionRegistryPostProcessors顺序
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			//接下来获取所有获取Ordered接口的BeanDefinitionRegistryPostProcessor。 Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			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));
					// 即便是实现了PriorityOrdered和Ordered,只会处理PriorityOrdered
					processedBeans.add(ppName);
				}
			}
			// 按照顺序排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行这些BeanDefinitionRegistryPostProcessors顺序
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			//最后,我们自定义的一般没有任何优先级和排序接口 Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				// 拿到所有的BeanDefinitionRegistryPostProcessor
				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);
				// 执行BeanDefinitionRegistryPostProcessors逻辑
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				currentRegistryProcessors.clear();
			}

			//接下来,再来执行postProcessBeanFactory方法 Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
  • ⑤. 调用构造方法进行插件,执行构造方法中的操作
    在这里插入图片描述在这里插入图片描述

  • ⑥. 执行自定义类中的MyBeanDefinitionRegistryPostProcessor方法
    在这里插入图片描述

⑤. BeanFactoryPostProcessor后置处理器执行

  • ①. 前面执行完postProcessBeanDefinitionRegistry方法之后,在后面有这样两行代码,会去执行invokeBeanFactoryPostProcessors
boolean reiterate = true;
while (reiterate) {
	reiterate = false;
	// 拿到所有的BeanDefinitionRegistryPostProcessor
	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);
	// 执行BeanDefinitionRegistryPostProcessors逻辑
	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
	currentRegistryProcessors.clear();
}

//接下来,再来执行postProcessBeanFactory方法 Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  • ②. 这样以后,我们的MyBeanDefinitionRegistryPostProcessor类中的postProcessBeanFactory方法里面也会去执行

⑥. 处理器应用 - Configuration

  • ①. 以注解方式debug启动,并给IOC容器刷新的关键12大步里面的invokeBeanFactoryPostProcessors(beanFactory)执行所有的BeanFactory后置增强这一块打上一个断点,也给主配置类方面的无参构造打一个断点。如下图所示【增强器应用 - Configuration断点位置】

在这里插入图片描述

	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);

在这里插入图片描述

  • ②. 我们在postProcessBeanDefinitionRegistry方法上打一个断点。可以看到启动后,在底层拿到了有一个叫ConfigurationClassPostProcessor的后置处理器(配置类的增强)

在这里插入图片描述

  • ③. 把配置类中所有bean的定义信息导入进来
    在这里插入图片描述
  • ④. 遍历beanName,这里我们拿到最后一个我们自己的myConfig,拿到后,将配置类加到后续集合等待处理
    在这里插入图片描述
    在这里插入图片描述
  • ⑤. 对所有的配置类进行排序,然后生效

在这里插入图片描述

  • ⑥. 创建一个internalConfigurationBeanNameGenerator用来生成配置类的名字(这里是在工厂创建好了之后,就去解析配置类)
	public static final String CONFIGURATION_BEAN_NAME_GENERATOR =
			"org.springframework.context.annotation.internalConfigurationBeanNameGenerator";

在这里插入图片描述

  • ⑦. 由parser解析每一个配置类
    在这里插入图片描述
  • ⑧. 如何进行解析的,我们点进去parse方法去看一看。最后有一个do while循环,while那里是只要配置类不为空,就挨个解析所有配置类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • ⑨. 进入doProcessConfigurationClass方法后,可以看到Component是如何解析的,bean是如何解析的
    先判断配置类里边是不是标注了Component注解,并且看看配置类里边的PropertySources注解,再看看配置类里边标的ComponentScans,然后各个不同的注解进入不同的解析方法来进行解析
	protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {
		// 配置配是不是标注了Component
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first
			processMemberClasses(configClass, sourceClass, filter);
		}

		// Process any @PropertySource annotations
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class,
				org.springframework.context.annotation.PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			}
			else {
				logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}

		// Process any @ComponentScan annotations
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// Check the set of scanned definitions for any further config classes and parse recursively if needed
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations");
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		//处理@Bean注解 Process individual @Bean methods
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// Process default methods on interfaces
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// Superclass found, return its annotation metadata and recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}
Spring中的前置处理器后置处理器是用来在Bean的实例化和初始化过程中进行一些额外的处理的。前置处理器BeanFactoryPostProcessor接口的实现类,它在Spring容器加载Bean的定义之后,实例Bean之前进行一些配置的修改或者其他操作。它可以对Bean的定义进行解析和修改,最终将修改后的Bean定义添加到SpringBeanDefinitionMap中。\[1\]后置处理器BeanPostProcessor接口的实现类,它在Bean的实例化和初始化过程中,对Bean进行一些额外的处理。它可以在Bean实例化后对Bean进行修改,也可以在Bean初始化前后对Bean进行一些操作,比如动态代理等。\[2\]在调用前置处理器的时候,Spring会按照优先级进行分类调用。实现了PriorityOrdered接口的前置处理器会先被调用,然后是实现了Ordered接口的前置处理器,最后是没有实现这两个接口的前置处理器。\[3\]这样可以确保前置处理器按照指定的顺序进行调用,以满足不同的需求。 #### 引用[.reference_title] - *1* *3* [攀登Spring珠穆朗玛峰:前置与后置处理器](https://blog.csdn.net/qq_38289451/article/details/122226807)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Spring Bean前置后置处理器的使用](https://blog.csdn.net/weixin_40834464/article/details/82832173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

所得皆惊喜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值