Springアノテーションドライバー(拡張原理):BeanFactoryPostProcessorおよびサブインターフェイス、ApplicationListener、@ EventListener

拡張原理BeanFactoryPostProcessor

package jane.ext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/*
 * 扩展原理:
 * 类似的:BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作
 * BeanFactoryPostProcessor:beanFactory的后置处理器
 * 原码解析:
 * 	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 在BeanFactory标准初始化之后可以调用它修改BeanFactory,
	 标准初始化就是所有的bean定义信息已经保存加载到beanfactory,但是bean的实例还没创建
	 
	步骤:
		1)IOC容器创建对象
			1)invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors
			任何找到所有的BeanFactoryPostProcessor并且执行他们的方法
				
				List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
				for (String postProcessorName : nonOrderedPostProcessorNames) {
					nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
				}
				invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
			
		private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
			for (BeanFactoryPostProcessor postProcessor : postProcessors) {
				postProcessor.postProcessBeanFactory(beanFactory);
			}
	}
			
				1)直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
		这些方法都是在创建其他组件前面执行的
 */

import jane.bean.Car;
@ComponentScan("jane.ext")
@Configuration
public class MyConfigOfExt
{
    
    
	@Bean
	public Car car()
	{
    
    
		return new Car();
	}
}

package jane.ext;

import java.util.Arrays;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
    
    
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
	{
    
    
		System.out.println("MyBeanFactoryPostProcessor.postProcessBeanFactory");
		int count = beanFactory.getBeanDefinitionCount();
		String[] names = beanFactory.getBeanDefinitionNames();
		System.out.println("定义的bean的个数:"+count);
		System.out.println(Arrays.toString(names));
	}

}

BeanDefinitionRegistryPostProcessor

これはBeanFactoryPostProcessorのサブインターフェイスです
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
。抽象メソッドvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistry Registry)がBeansExceptionをスローします。
このメソッドは、すべてのBean定義情報がロードされようとしていて、Beanインスタンスが作成されていない場合に呼び出されます。これ

BeanFactoryPostProcessorの実行よりも優先され、BeanDefinitionRegistryPostProcessorを使用していくつかのコンポーネントを追加します

対応する実装クラス

package jane.ext;

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

import jane.bean.Car;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor
{
    
    

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
	{
    
    
		System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:"+beanFactory.getBeanDefinitionCount());
	}
	/*
	 * BeanDefinitionRegistry是bean定义信息的保存中心,以后的BeanFactory就是按照
	 * BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例的
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException
	{
    
    
		System.out.println("postProcessBeanDefinitionRegistry的bean数量"+registry.getBeanDefinitionCount());
		/*
		 * 我们还可以使用BeanDefinitionRegistry来注册一些bean
		 * 注册bean需要beanDefinition(bean的定义信息),有很多方法创建beanDefinition
		 */
//		RootBeanDefinition beanDefinition = new RootBeanDefinition(Car.class);
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class).getBeanDefinition();
		registry.registerBeanDefinition("hello", beanDefinition);
	}

}

結果

九月 09, 2020 7:29:16 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 19:29:16 CST 2020]; root of context hierarchy
postProcessBeanDefinitionRegistry的bean数量10
MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:11
MyBeanFactoryPostProcessor.postProcessBeanFactory
定义的bean的个数:11
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, myConfigOfExt, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, car, hello]
九月 09, 2020 7:29:16 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
car constructor...
car constructor...
九月 09, 2020 7:29:16 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 19:29:16 CST 2020]; root of context hierarchy

元のコードビュー

まず、IOCコンテナを作成してrefresh()を
呼び出し、コンテナを更新してinvokeBeanFactoryPostProcessors(beanFactory)を
呼び出します。invokeBeanFactoryPostProcessorsを
呼び出してPostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory、getBeanFactoryPostProcessors())呼び出します。currentRegistryProcessorsのcurrentRegistryProcessorsがMyBeanDefinition
をどのように保存するかを確認できます
。それは?
ここに写真の説明を挿入
また、彼らは、同じBeanFactoryPostProcessorのように、取得するには貫通型、または優先順位に基づいて取得することがわかり、その後、invokeBeanDefinitionRegistryPostProcessorsを行う()メソッドを可能
ここに写真の説明を挿入
ここに写真の説明を挿入
し、その後postProcessBeanFactory BeanFactoryPostProcessorインターフェイス()メソッドをトリガーするここに写真の説明を挿入
BeanFactoryPostProcessorインタフェースよりも方法なぜBeanDefinitionRegistryPostProcessorの道を以前に実行する必要がありますか?
BeanFactoryPostProcessorインターフェイスのメソッドがこのメソッドの後に実行されていることがわかります
ここに写真の説明を挿入

ApplicationListener

package jane.ext;

import java.util.EventListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/*
 * ApplicationListener:监听容器中发布的事件,实现事件驱动模型开发
 * public interface ApplicationListener<E extends ApplicationEvent> extends EventListener 
 * 监听ApplicationEvent及其下面的子事件
 * 
 * 步骤:
 * 	1.先写一个监听器来监听某个事件(ApplicationEvent及其子类)
 * 	2.把监听器加入到容器中
 * 	3.只要是容器中有关事件的发布,我们就能监听到这个事件
 * 			
 * 			ContextRefreshedEvent:容器刷新完成(所有的bean都完成创建)就会发布这个事件
 * 			ContextClosedEvent:关闭容器就会发布这个事件
 * 	4.自己发布一个事件
 */
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>
{
    
    

	@Override
	public void onApplicationEvent(ApplicationEvent event)
	{
    
    
		System.out.println("收到事件"+event);
	}

}

テスト

package jane;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import jane.ext.MyConfigOfExt;

public class IOCTestExt
{
    
    
	@org.junit.Test
	public void TestExt()
	{
    
    
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfExt.class);
		applicationContext.publishEvent(new ApplicationEvent(new String("自己发布事件")){
    
    });
		applicationContext.close();
	}
}

結果

九月 09, 2020 8:17:00 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy
postProcessBeanDefinitionRegistry的bean数量11
MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:12
MyBeanFactoryPostProcessor.postProcessBeanFactory
定义的bean的个数:12
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, myConfigOfExt, myApplicationListener, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, car, hello]
九月 09, 2020 8:17:00 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
car constructor...
car constructor...
收到事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy]
收到事件jane.IOCTestExt$1[source=自己发布事件]
九月 09, 2020 8:17:01 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy
收到事件org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy]

原理

元のコードをデバッグして、上記の3つのイベントがどのように作成されるかを確認します。
まず、コンテナはオブジェクトを作成します
。refresh();コンテナは更新されてfinishRefresh()が呼び出されます。コンテナの更新が完了したら、入力して確認します
ここに写真の説明を挿入
。呼び出されるのはpublishEvent(new ContextRefreshedEvent(this));リリースです。コンテナの更新が完了したイベント
はpublishEvent()に入り、イベントがどのように公開されるかを確認しますか?
イベント公開プロセス

	@Override
	public void publishEvent(ApplicationEvent event) {
    
    
		publishEvent(event, null);
	}

publishEvent(event、null);と入力
すると、最初にイベントマルチキャスト(ディスパッチャ)getApplicationEventMulticaster()
取得し、次にmulticastEvent(applicationEvent、eventType)を実行してイベントを配信します
ここに写真の説明を挿入
。どのように配信しますか?multicastEvent()に移動し
て、最初のイベントがすべてのApplicationListenersを取得します。Executorがある場合は、
非同期ディスパッチ(もう1つのスレッドを開く)のためのExecutorの使用をサポートできます。これは、より効率的です。
そうでない場合は、リスナーメソッドinvokeListener(listener、event)を同期的に直接実行し、
次にこれらをinvokeで実行します。メソッド実行ルーチンはほぼ同じ
です。doInvokeListener(listener、event);
を呼び出してから、リスナーにonApplicationEventメソッドをコールバックさせます。
listener.onApplicationEvent(event);
ここに写真の説明を挿入
上記を読んだ、この質問があります。イベントマルチキャスター(ディスパッチャー)は何をしていますか?

applicationEventMulticaster

または、通常のルーチンでは、コンテナはオブジェクトを作成します。refresh ();更新する
ときinitApplicationEventMulticaster()は、applicationEventMulticasterを初期化し
ここに写真の説明を挿入
、initApplicationEventMulticaster()入力します
最初にコンテナに移動して、id = "applicationEventMulticaster"のコンポーネント
あるかどうかを確認します。ない場合は、SimpleApplicationEventMulticaster
作成してコンテナに追加します。他のコンポーネントでイベントをディスパッチし、applicationEventMulticaster
ここに写真の説明を挿入
自動的に挿入し、どのリスナーが
コンテナー内にあるかをどのように知ることができますか?コンテナーはオブジェクトを作成し、refresh();
registerListeners()があり、登録されたリスナー
ここに写真の説明を挿入
はコンテナーからすべてのリスナーを取得します。リスナー、それらをマルチキャストに登録します。リスナーはタイプごとに見つかります
ここに写真の説明を挿入

@EventListener

package jane.ext;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class TestListener
{
    
    
	@EventListener({
    
    ApplicationEvent.class})
	public void listener(ApplicationEvent event)
	{
    
    
		System.out.println("TestListener收到监听事件"+event);
	}
}

原理

EventListenerMethodProcessorプロセッサを使用して、メソッドの@EventListenerを解析します。
次に、EventListenerMethodProcessorに入ります
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware {
。EventListenerMethodProcessorはSmartInitializingSingletonを実装します。このSmartInitializingSingletonは、チェックする原則です
。SmartInitializingSingletonビューに入ります
。このメソッドが実行されます。
トリガーのタイミングはContextRefreshedEventに似ています。
ここに写真の説明を挿入
次に、デバッグして呼び出し原理を表示します。
最初に、IOCコンテナーがオブジェクトを作成し、refresh()
、次にfinishBeanFactoryInitialization(beanFactory);残りの単一インスタンスBeanを初期化します
。beanFactory.preInstantiateSingletons();
1)最初にすべての注文を作成しますインスタンスBean、getBean();
2)次に、作成されたすべてのシングルインスタンスBeanを取得し、それらがSmartInitializingSingletonタイプであるかどうかを判別します。
そうである場合は、afterSingletonsInstantiated();を呼び出します。

おすすめ

転載: blog.csdn.net/qq_43416157/article/details/108434074