ホームページ >Java >&#&チュートリアル >SpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法
この記事で作成したサンプル プロジェクトは、SpringBoot 2.2.1.RELEASE
maven 3.5.3
idea# を使用して開発されています。
application.yml、
public class ApplicationContextInitializer01 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer01"); } }2. 拡張ポイントの登録 上記の拡張ポイントをカスタマイズします。有効にするにはどうすればよいですか? 公式では、起動時に直接登録するなど、次の 3 つの方法が提供されています。
springApplication.addInitializers(new ApplicationContextInitializer01());
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addInitializers(new ApplicationContextInitializer01()); try (ConfigurableApplicationContext context = springApplication.run(args)) { } } }拡張ポイントが提供されるときjar パッケージで外部に公開する場合、上記の起動登録方法を使用することは明らかに現実的ではありません。現時点では、Spring の SPI メカニズムを介してリソース ディレクトリ に登録することをお勧めします。 META-INF/spring.factories
ファイルに登録<pre class="brush:java;">org.springframework.context.ApplicationContextInitializer=com.git.hui.extention.context.ApplicationContextInitializer02</pre>
は通常この方法で登録されます
または application.yml
で、次のように構成します <pre class="brush:java;">context:
initializer:
classes: com.git.hui.extention.context.ApplicationContextInitializer03</pre>
上記3 つの登録方法を使用して、3 つのカスタマイズされた拡張ポイントを実装し、開始後に実際の出力を確認します。
上記の出力は、単に結論を導き出すことができます。異なる登録方法の優先順位(以下の観点をより合理的に検証するために、上記の 3 つのカスタム拡張子を変更して、拡張子によるソートの問題を解決することをお勧めします)
#設定ファイルの登録> SPI の登録 > 起動時の登録@Order(5) public class ApplicationContextInitializer01 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer01"); } } @Order(2) public class ApplicationContextInitializer02 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer02"); } } @Order(10) public class ApplicationContextInitializer03 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("ApplicationContextInitializer03"); } } @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addInitializers(new ApplicationContextInitializer01(), new ApplicationContextInitializer02(), new ApplicationContextInitializer03()); try (ConfigurableApplicationContext context = springApplication.run(args)) { } } }
出力例は次のとおりです
##ここからが重要なポイントです。
上記 3 つのカスタム実装が同じ登録方法ではない場合、たとえば、03 の登録には構成ファイルによる方法を使用します。 、その後 01、02 で登録が開始されます
アノテーション変更の順序は、
Configuration File>SPI>Startup Mode Registrationカスタム実装の実行順序について
最後に、内容を見てみましょう。この拡張ポイントの用途は次のとおりです。これはどのようなシナリオで使用されますか?
public class ApplicationContextInitializer03 implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { // 指定激活prod对应的配置文件 configurableApplicationContext.getEnvironment().setActiveProfiles("prod"); } }しかし、構成パラメーターを直接使用するだけなので、一般にこれを行う人はほとんどいません。それで、これを必要とするシナリオはありますか? 答えはもちろん「はい」です。たとえば、現在広く普及している Docker コンテナのデプロイメントで、毎回同じイメージを使用し、実際の運用中に使用したい場合は、次のように現在のイメージを決定できます。どの構成ファイルが有効になっているかがこの時点で役に立ちます。たとえば、コンテナの環境パラメータ
app.env
を使用して、現在の実行環境を取得します。それが prod の場合、 activateapplication-prod.yml
; テストの場合は、activateapplication-test.yml
この時点でこれを行うことができます
public class EenvActiveApplicationContextInitializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { String env = System.getenv("app.env"); if ("prod".equalsIgnoreCase(env)) { configurableApplicationContext.getEnvironment().setActiveProfiles("prod"); } else if ("test".equalsIgnoreCase(env)) { configurableApplicationContext.getEnvironment().setActiveProfiles("test"); } else { throw new RuntimeException("非法的环境参数:" + env); } } }
以上がSpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。