4つの分析ソースの春シリーズ:のBeanFactoryPostProcessor春スキャンコンポーネント

テストクラスを準備する1

public class Test01 {
	public static void main(String[] args) {
		//这个构造方法会把Spring所有的环境都准备好
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
	}
}
复制代码

Configurationクラス

@ComponentScan("com.v1")
@Component
@Configuration
public class SpringConfiguration {

}
复制代码

PersonServiceクラス

@Component
public class PersonService {
}
复制代码

2.AnnotationConfigApplicationContext

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
		//调用无参构造方法进行初始化一个读取器和扫描仪
		this();
		//把配置类加载进 DefaultListableBeanFactory 的map集合中
		//配置类可以一次性传多个,这个方法执行后,只是把配置类加载进了 DefaultListAbleBeanFactory的map集合中
		//还没有扫描其他的的加了组件的类
		register(annotatedClasses);
		//实例化所有被加了组件的对象
		refresh();
	}
复制代码

3.refresh()

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
			//这个方法不是重点,可以暂时认为他不干任何事情
			prepareRefresh();

			//获取工厂对象 ,本质是DefaultListableBeanFactory对象
			//其实读取xml文件变成beanDefinition,也是在这里面完成的
			//所以这里面的功能和register(annotatedClasses);功能很像
			//一个是是从xml文件中读取配置信息,一个是通过类的注解读取信息
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//为BeanFactory配置类加载器、后置处理器等等
			//这个方法比较重要
			prepareBeanFactory(beanFactory);

			try {
				//这个方法是空方法,Spring还没有做任何事情
				//猜测以后Spring会使用这个方法
				postProcessBeanFactory(beanFactory);


				//在这个方法中开始扫描被组件标记的类, 把类的信息
				// 封装成一个GenericBeanDefinition存储在map集合中
				//这个是非常重要的一个方法
				invokeBeanFactoryPostProcessors(beanFactory);
				
				//省略剩余代码...
				
				}
复制代码

4. invokeBeanFactoryPostProcessors(beanFactory)

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

//重点方法,执行beanFactoryPostProcessors后置处理器
//注意这里 getBeanFactoryPostProcessors() 是获取不到用户自己的BeanFactoryPostProcessor的实现类的 ,因为这个时候还没有开始扫描包
//需要自己手动赋值给这个大容器对象,也就是AnnotationConfigApplicationContext
//ac.addBeanFactoryPostProcessor(....);
//getBeanFactoryPostProcessors()可以获取到用户自定义的作用类,前提是手动创建,传进来的	
    
 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
复制代码

5. invokeBeanFactoryPostProcessors

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

// 1. 处理用户自己的后置处理器,处理的是用户自己创建对象传的ac.addBeanFactoryPostProcessor()
//如果你想在扫描所有包之前就执行你的后置处理器的话,可以首先把的后置处理器注册给Spring
//就是通过 ac.addBeanFactoryPostProcessor(对象) 这样子注解
		Set<String> processedBeans = new HashSet<>();
           //判断当前的beanFactory是否是BeanDefinitionRegistry
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//定义两个集合BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor
//bdrpp 增强了一个功能 ,也就是说他们的功能是不一样的,所以需要定义两个集合
//regularPostProcessors 存储用户自己传进来的BeanFactoryPostProcessor的实现类
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors存储用户自己传进来的BeanDefinitionRegistryPostProcessor的实现类
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断的bean是否实现了BeanDefinitionRegistryPostProcessor
//如果bean实现了BeanDefinitionRegistryPostProcessor这个接口,可以获取到整个容器对象,也就是registry对象
//而实现BeanFactoryPostProcessor,只能获取 到bean工厂 对象
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					//如果当前的bean实现的是BeanDefinitionRegistryPostProcessor
					//添加进registryProcessors集合
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					//如果只是实现了beanFactoryPostProcessors添加进regularPostProcessors集合
					regularPostProcessors.add(postProcessor);
				}
			}
  //其实前面都不是重点,基本不会有人自己手动创建对象添加给Spring容器的,以下才是重点

//2.处理Spring内部的后置处理器,Spring内部的处理器 ,就只有一个类实现BeanDefinitionRegistryPostProcessor
//currentRegistryProcessors存放Spring内部类实现了BeanDefinitionRegistryPostProcessor接口的类
//ConfigurationClassPostProcessor 这个就是实现类 BeanDefinitionRegistryPostProcessor
//ConfigurationClassPostProcessor就是Spring内部的后置处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

//从beanFactory工厂中寻找判断哪个类型实现了BeanDefinitionRegistryPostProcessor接口,拿出该类的beanName
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			//遍历所有的后置处理器beanName ,通过beanName从bean工厂中把对象取出来
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//把名称存储到processedBeans集合中
					processedBeans.add(ppName);
				}
			}
			//排序,不是重点 ,内部只有一个
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//合并list ,把用户之间定义和Spring之间内部的合并在一个集合中
            //合并基本是没有用的,一般用户不会自己手动创建对象注册进Spring容器
			registryProcessors.addAll(currentRegistryProcessors);

             //执行当前的后置处理器,其实到这里currentRegistryProcessors只有一个处理器,
			//主要处理扫描配置类对应包下的类
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空集合
			currentRegistryProcessors.clear();
		  //剩余代码省略....其实下面的代码也有一部分很重要的,以后再聊
        
			}
复制代码

このメソッドがした主なものは何ですか?

Springコンテナ横断beanDefinitionMapコレクションはどのクラスが実装を見つけるBeanDefinitionRegistryPostProcessorインターフェース

独自の春のコンテナの設定に加えて、この時点で、なおSpringConfigurationこのクラスは、まだ彼らの春のコンテナに任意のクラス定義をスキャンするために開始されていません

知ってはいけないSpringConfigurationSpringコンテナにロードするために何時間、あなたが見ることができます:

【春ソースを解析する一連の:クラス初期化プロセス構成] juejin.im/post/5d7b7b ...

この時、春のコンテナはbeanDefinitionMap、一つだけ私たちの定義されたクラスのSpringConfiguration、残りは内部クラスの春に定義されています

実際には春の内部で定義されたクラスのみが実現されBeanDefinitionRegistryPostProcessor、このインターフェイスがあります

ConfigurationClassPostProcessorこのクラスは、スキャンコンポーネント重要な役割として春です

6.アイデアをダブルクリックしてクエリ `ConfigurationClassPostProcessor

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
      PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware
复制代码

7.BeanDefinitionRegistryPostProcessor

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}
复制代码

8. BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * 自己定义一个类,重写这个方法,可以获取到 bean工厂,插手bean的实例化过程
	 * 获取到bean工厂对象
	 *
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
复制代码

BeanFactoryPostProcessorそして、BeanPostProcessorちょうど春の拡張として一点

それはどのような違いの両方を作るん?

BeanPostProcessor

public interface BeanPostProcessor {

	/**
	 * 在bean的初始化之前执行
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * 在bean的初始化之后执行
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
复制代码
  • beanPostProcessorBeanレベル、Beanに処理されている、beanPostProcessor実行前とBeanがインスタンス化された後に行われます

  • 実装beanPostProcessorインタフェースは、Beanのインスタンス化を妨げる可能性が

理解していないbeanPostProcessor役割を、あなたは見ることができます

[春のポストプロセッサ、最後にはそれがどのように?ある] Juejin.im/post/5df066 ...

BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * 自己定义一个类,重写这个方法,可以获取到 bean工厂,插手bean的实例化过程
	 * 获取到bean工厂对象
	 *
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
复制代码
  • BeanFactoryPostProcessorそれは、全体の豆の加工工場のためたBeanFactoryレベルです
  • BeanFactoryPostProcessorプラント全体は可能BeanDefinitionであっても、カスタム、干渉することBeanDefinitionSpringコンテナに登録します

BeanFactoryPostProcessor実行優先順位を超えます BeanPostProcessor

BeanFactoryPostProcessor記載されているクラスで行われBeanDefinition、以下、

BeanPostProcessor豆で行われるインスタンス化されます

9.私たちをバック ConfigurationClassPostProcessor

ConfigurationClassPostProcessorこのクラスは、実際にこの豆の植物を扱うポストプロセッサであります

このクラスの実装はBeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor継承されてきました

BeanFactoryPostProcessorインターフェース

ConfigurationClassPostProcessorプロセッサの役割は、以下のとおりです。

構成タイプ読み取るSpringConfiguration走査するように情報が追加される@Componentコンポーネントは、パッケージされたBeanDefinition容器春に添加し

9.概要

この章では、このプロセスでは、我々はポストプロセッサを描いた、プロセス春Springコンテナの一部に走査素子を強調しBeanFactoryPostProcessor、比較BeanFactoryPostProcessorし、beanPostProcessor違いを

次の章を書きます:

ConfigurationClassPostProcessorコンテナ春にスキャンコンポーネントは、どのようにエンド・コンポーネントであります

ビデオチュートリアル:

www.bilibili.com/video/av678...

ビデオは、自分自身の学習のための時間を記録するだけでなく、彼らの将来の外観を促進します

Spring5ソースアドレス:

github.com/zouchangfu/...の gitee.com/zouchangfu/...

Spring5は、すでに実行することができ、直接オープン、良い情報源、およびのGradleを構築するために使用することはもはや必要性を構築されています

最後に書かれました:

二年生は、ブログを書くために時間を絞る賞賛を読みやすいポイント、あなたのポイントは、私の最大の励ましで賞賛することは容易ではありません

おすすめ

転載: juejin.im/post/5df4937a51882512591aabfe