ホームページ  >  記事  >  Java  >  SpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法

SpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法

WBOY
WBOY転載
2023-05-11 08:58:111000ブラウズ

I. プロジェクトの準備

この記事で作成したサンプル プロジェクトは、SpringBoot 2.2.1.RELEASE maven 3.5.3 idea# を使用して開発されています。

## 特定の SpringBoot プロジェクトの作成については詳しく説明しません。コア pom ファイルには追加の依存関係は必要ありません。

構成ファイル

application.yml

II. コンテナー更新前の拡張ポイント インスタンス

1. カスタム ApplicationContextInitializer

カスタム コンテキストの初期化を実装する場合、それは非常に簡単です。単純に、上記のインターフェイスを実装するだけです (例:

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>

手順

    上記の SPI メカニズムは、すべての人に強くお勧めします。以前の記事では、
  • AutoConfiguration

    は通常この方法で登録されます

  • 上記の 2 つの登録方法に加えて、設定ファイル メソッドもあります。構成ファイル
application.properties

または application.yml で、次のように構成します <pre class="brush:java;">context: initializer: classes: com.git.hui.extention.context.ApplicationContextInitializer03</pre>

テストを開始します

上記3 つの登録方法を使用して、3 つのカスタマイズされた拡張ポイントを実装し、開始後に実際の出力を確認します。

SpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法上記の出力は、単に結論を導き出すことができます。異なる登録方法の優先順位(以下の観点をより合理的に検証するために、上記の 3 つのカスタム拡張子を変更して、拡張子によるソートの問題を解決することをお勧めします)

#設定ファイルの登録> SPI の登録 > 起動時の登録
  • 3. 実行順序の指定
カスタム拡張ポイントの実装では、順序関係がある場合、## を通じてこれを実現できます。 #@Order

アノテーション。たとえば、上記の 3 つの拡張ポイントがすべてスタートアップ メソッドで登録された場合、

@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)) {
        }
    }
}

出力例は次のとおりです

##ここからが重要なポイントです。

SpringBootコンテナが更新される前にApplicationContextInitializerをコールバックする方法

上記 3 つのカスタム実装が同じ登録方法ではない場合、たとえば、03 の登録には構成ファイルによる方法を使用します。 、その後 01、02 で登録が開始されます

    、順序は 03 > 02 > 01
  • つまり
  • @Order

    アノテーション変更の順序は、

    Configuration File>SPI>Startup Mode Registration
  • カスタム実装の実行順序について

    #設定ファイル> SPI> 起動メソッド

同じ登録メソッドを渡すことができます
    @Order
  • アノテーションは変更に使用されます。値が小さいほど優先度が高くなります。

  • 4. 使用シナリオの例

    最後に、内容を見てみましょう。この拡張ポイントの用途は次のとおりです。これはどのようなシナリオで使用されますか?

    一般的なアプリケーション シナリオは、アクティブ化する必要がある構成ファイルを指定するためにこれを使用することです。
  • public class ApplicationContextInitializer03 implements ApplicationContextInitializer {
        @Override
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            // 指定激活prod对应的配置文件
            configurableApplicationContext.getEnvironment().setActiveProfiles("prod");
        }
    }
しかし、構成パラメーターを直接使用するだけなので、一般にこれを行う人はほとんどいません。それで、これを必要とするシナリオはありますか?

答えはもちろん「はい」です。たとえば、現在広く普及している Docker コンテナのデプロイメントで、毎回同じイメージを使用し、実際の運用中に使用したい場合は、次のように現在のイメージを決定できます。どの構成ファイルが有効になっているかがこの時点で役に立ちます。

たとえば、コンテナの環境パラメータ

app.env

を使用して、現在の実行環境を取得します。それが prod の場合、 activate

application-prod.yml

; テストの場合は、activate

application-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 サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。