Springboot 拡張ポイント シリーズの実装方法と動作原理のコレクション:
Springboot 拡張ポイント ApplicationContextInitializer
Springboot 拡張ポイント BeanFactoryPostProcessor
Springboot 拡張ポイント BeanDefinitionRegistryPostProcessor
Springboot 拡張ポイント BeanPostProcessor
Springboot 拡張ポイント InstantiationAwareBeanPostProcessor
Springboot 拡張ポイント SmartInstantiationAwareBeanPostProcessor
Springboot 拡張ポイント ApplicationContextAwareProcessor
Springboot 拡張ポイント @PostConstruct
Springboot 拡張ポイント InitializingBean
Springboot 拡張ポイント SmartInitializingSingleton
Springboot 拡張ポイント CommandLineRunner および ApplicationRunner
Springboot 拡張ポイント FactoryBean
Springboot 拡張ポイント DisposableBean
Springboot 拡張ポイント シリーズの終わり: Bean のライフサイクル
序文
Spring と Springbooboot に関して言えば、多くの人はすぐに依存関係の注入、制御の反転、自動アセンブリ、構成よりも規約、開発の容易化などを思い浮かべるでしょう。しかし、Springboot と SpringMVC を使用して追加、削除、変更、クエリを実行し、いくつかのバグを解決するだけであれば、実際には Spring や Springboot をよく理解していないことになります。Spring の中核はコンテナであり、Springboot は Spring をカプセル化し、内部の複雑さを隠して使いやすくし、同時に多くの拡張機能を確保します。したがって、Springboot の簡単な使い方を学ぶことは単なる始まりにすぎないと思いますが、ビジネス開発にとってより役立つのは、Springboot が複雑さをどのようにシンプルにし、予約された拡張インターフェイスを使用するかということです。
1. ApplicationContextInitializerの機能
Spring コンテナの初期化が開始されると、ApplicationContextInitializer インターフェースのすべての実装がクラス内でインスタンス化され、
Spring コンテナが更新される前に、すべての実装クラスの org.springframework.context.ApplicationContextInitializer#initialize メソッドが呼び出され、仮パラメータが初期化メソッドの種類 ConfigurableApplicationContext であるため、ApplicationContextInitializer は実際には Spring コンテナが初期化される前の ConfigurableApplicationContext のコールバック インターフェイスであると考えることができ、環境属性の登録の実行、設定ファイルのアクティブ化など、コンテキスト環境に対していくつかの操作を実行できます、など。
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
/**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext);
}
2. 3つの実装方法
特定の実装クラスを通じて ApplicationContextInitializer インターフェイスを実装することにより、特定の実装メソッドを共有しましょう。Springboot の拡張ポイント ApplicationContextInitializer インターフェイスの実装は、主に 2 つのステップに分かれています。
1. ApplicationContextInitializer インターフェイスを実装します。
MyApplicationContextInitializer は、ApplicationContextInitializer インターフェイスを実装し、システム関連の属性のキーと値を出力します。
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
Map<String, Object> systemProperties = applicationContext.getEnvironment().getSystemProperties();
System.out.println("---------------start------------------");
systemProperties.forEach((key,value)->{
System.out.println("key:"+key+",value:"+value);
}); System.out.println("---------------end------------------");
}
}
2.実装クラスをSpringコンテナに登録する
実装クラス MyApplicationContextInitializer を Spring コンテナに登録するには、主に 3 つの方法があります。
2.1 spring.factories
リソース ディレクトリに新しい /META-INFI/spring.factories ファイルを作成し、次の内容をプリセットして、カスタマイズされた MyApplicationContextInitializer の登録を完了します。
org.springframework.context.ApplicationContextInitializer=com.fanfu.config.MyApplicationContextInitializer
2.2 アプリケーションのプロパティ
application.properties ファイルに次の構成内容を事前設定して、カスタマイズされた MyApplicationContextInitializer の登録を完了します。
context.initializer.classes=com.fanfu.config.MyApplicationContextInitializer
2.3 springApplication.addInitializers()
springboot スタートアップ クラスで、 springApplication.addInitializers(new MyApplicationContextInitializer()) を使用して、カスタム MyApplicationContextInitializer の登録を完了します。
@SpringBootApplication
public class FanfuApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(FanfuApplication.class);
springApplication.addInitializers(new MyApplicationContextInitializer());
springApplication.run(args);
}
}
実行結果は以下の通りです。 (user.dir=プロジェクトのルートディレクトリ)
3. 初期化タイミング
ApplicationContextInitializer インターフェイスの実装クラスは、SpringApplication クラスのコンストラクターで初期化されます。つまり、Spring コンテナーの初期化が開始される前に、すべての実装クラスのコレクションが getSpringFactoriesInstances(…) によって最初に取得され、次に、その initializersn 属性に注入されます。 SpringApplication クラスから setInitializers(…) 中間まで。
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
4. 実行タイミング
ApplicationContextInitializer インターフェースの実装クラスの実行時間は org.springframework.boot.SpringApplication#prepareContext–>org.springframework.boot.SpringApplication#applyInitializers 内にあります。つまり、Spring コンテナーが正式に更新される前にコンテキスト環境が準備されるときです。 ;
getInitializers() は、SpringApplication クラスのコンストラクターの setInitializers(...) を通じて SpringApplication クラスのInitializersn 属性に注入される ApplicationContextInitializer インターフェイスのすべての実装クラスを取得し、これらの実装クラスをトラバースして、initialize() メソッドを呼び出します
。
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
5. 組み込み実装クラス
Springboot には、Spring 関連関数の実装を支援するいくつかの組み込み実装クラスもあります。一般的な実装クラスは次のとおりです。
5.1 DelegatingApplicationContextInitializer
ApplicationContextInitializer (application.properties) の 2 番目の実装メソッドは、application.properties ファイルで context.initializer.classes=com.fanfu.config.MyApplicationContextInitializer を構成することです。DelegatingApplicationContextInitializer の機能は、application.properties で構成された実装クラスを見つけることです。ファイルを作成してインスタンス化し、initialize() メソッドを実行します。
5.2 ContextIdApplicationContextInitializer
ContextIdApplicationContextInitializer は、Spring アプリケーションのコンテキスト ID を設定するために使用されます。 application.properties に spring.application.name が設定されていない場合、デフォルトは "application" になります。
5.3 構成警告ApplicationContextInitializer
ConfigurationWarningsApplicationContextInitializer は、Spring コンテナーの一般的な構成ミスを報告するために使用されます。イニシャライザーが Bean ポストプロセッサーをコンテキストに追加していることがわかります。このプロセッサは、BeanDefinition インスタンスの登録後に有効になり、登録プロセス中に生成されたアラーム情報を処理するために使用され、実際にログを通じてアラーム情報を出力します。
5.4 ServerPortInfoApplicationContextInitializer
ApplicationContextInitializer インターフェイスの実装に加えて、ServerPortInfoApplicationContextInitializer は ApplicationListener インターフェイスも実装します。ServerPortInfoApplicationContextInitializer の機能は、それ自体を Spring コンテキスト環境のリスナーとして登録することです。
5.5 SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor オブジェクトがインスタンス化され、Spring コンテキストに登録されます。CachingMetadataReaderFactoryPostProcessor は SharedMetadataReaderFactoryContextInitializer の内部クラスです。ここでは詳しく説明しません。興味のある友人は引き続き org .springframework.boot をフォローしてください。 .autoconfigure.SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry メソッドを使用して特定のコンテンツを理解します。
5.6 ConditionEvaluationReportLoggingListener
ConditionEvaluationReportLoggingListener は名前からリスナーのように見えますが、実際はそうではありません。その内部クラス org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener.ConditionEvaluationReportListener が実際のリスナーであり、ConditionEvaluationReportLoggingListener の機能は、内部クラス ConditionEvaluationReportListener をSpring コンテキスト。
6. まとめ
この記事を通じて、次のことを学ぶことができます。
-
まず、Spring コンテナが更新される前に、ApplicationContextInitializer インターフェイスを実装することで、Spring コンテキスト環境でいくつかの構成や操作を実行できます。
-
次に、ApplicationContextInitializer インターフェイスを実装するには 3 つの方法があり、プロジェクトのニーズに応じて適切な方法を選択できます。
-
第三に、ApplicationContextInitializer インターフェイス実装クラスの初期化タイミングと実行タイミング、および Springboot に組み込まれている特定の実装クラスを理解することで、Spring 自体が拡張インターフェイスを使用していくつかの機能を実装する方法を学ぶことができます。これは、実際のプロジェクトにとって一定の参照重要性を持ちます。発達。
—————————————
著作権に関する声明: この記事は CSDN ブロガー「Ordinary Trafficker」によるオリジナルの記事であり、CC 4.0 BY-SA 著作権契約に従っています。オリジナルのソース リンクとこのコピーを添付してください。声明を転載するとき。
元のリンク: https://blog.csdn.net/fox9916/article/details/128522598