拡張原理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();を呼び出します。