ホームページ  >  記事  >  Java  >  SpringBootのEnvironmentPostProcessorの使い方

SpringBootのEnvironmentPostProcessorの使い方

PHPz
PHPz転載
2023-05-22 09:25:051517ブラウズ

    1. 背景

    Apollo 構成センターは、前のプロジェクトで使用されました。Apollo 構成センターとドッキングした後、構成センターのプロパティはプログラム内で使用できますが、これはどのように実装されるのでしょうか?構成センターのプロパティがプログラムにロードされたのはいつですか?それでは、これがどのように実装されているかがわかったら、どこからでも 構成プロパティと構成プロパティの暗号化および復号関数をロードできるでしょうか?

    2. 要件

    SpringBootのEnvironmentPostProcessorの使い方

    上の図から、要件は非常に単純であることがわかります。設定ファイルよりも大きいファイルの方が優先されます。

    3. 分析

    1. SpringBoot に独自の構成プロパティを追加する場合

    Bean で構成プロパティを使用したい場合は、構成プロパティBean がインスタンス化される前に、Spring 環境に置く必要があります。つまり、

    アプリケーション コンテキストが更新される前にインターフェイスを呼び出す必要があります。EnvironmentPostProcessor はこの関数を正確に実装できます。 2. 設定プロパティの取得の優先順位

    Spring ではプロパティの取得に優先順位があることがわかっています。

    たとえば、次の構成プロパティがあります。

    username
    <pre class="brush:java;">├─application.properties │ &gt;&gt; username=huan ├─application-dev.properties │ &gt;&gt; username=huan.fu</pre>では、この時点での

    username

    の値は何でしょうか?この問題を説明するための Apollo の写真を次に示します。 参考リンク: https://www.apolloconfig.com/#/zh/design/apollo-design

    SpringBootのEnvironmentPostProcessorの使い方Spring はバージョン 3.1 から追加されました

    ConfigurableEnvironment

    および PropertySource: <pre class="brush:java;">ConfigurableEnvironment</pre>

      Spring の ApplicationContext には、Environment (ConfigurableEnvironment インターフェイスの実装) が含まれます
    • ConfigurableEnvironment 自体には多くの PropertySource
    PropertySource

      Property Source
    • #Key-Value 属性構成の数だけ理解できます

    • 上記の模式図からわかるように、

      key
    • は最初に表示されます
    PropertySource

    の優先度が高く、上記の例では、SpringBootusername の値は huan.fu です。 3. 独自の構成を追加する場合2 番目のステップから

    構成属性の優先順位を取得します

    PropertySource# の優先度が高いことがわかります。 ## の値が高いほど、最初に実行してから、構成を有効にするには、できるだけ早く配置する必要があります。

    上の図からわかるように、SpringBoot は

    EnvironmentPostProcessor

    を通じてさまざまな構成を読み込みます。具体的な実装は SpringBootのEnvironmentPostProcessorの使い方ConfigDataEnvironmentPostProcessor

    です。成し遂げる。次に、

    EnvironmentPostProcessor の実装クラスを自分で作成し、それを ConfigDataEnvironmentPostProcessor の後に実行し、Environment の最初の位置に追加します。 4. 実装

    1. SpringBoot 依存関係の導入SpringBootのEnvironmentPostProcessorの使い方

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.6</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.huan.springcloud</groupId>
        <artifactId>springboot-extension-point</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-extension-point</name>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    </project>

    2. application.properties でプロパティを設定

    vim application.properties
    username=huan

    3. カスタム属性を記述し、Spring 環境に追加します

    #注:

    1. プログラムにログ出力がない場合は、

    は slf4j

    を使用します ログを出力します 現在、ログシステムが初期化されていないため、ログを出力できません。 SpringBootのEnvironmentPostProcessorの使い方解決策は次のとおりです:

    SpringBoot版本
    		>= 2.4 可以参考上图中的使用 DeferredLogFactory 来输出日志
    		< 2.4
    			1、参考如下链接 https://stackoverflow.com/questions/42839798/how-to-log-errors-in-a-environmentpostprocessor-execution
    			2、核心代码:
    				@Component
    				public class MyEnvironmentPostProcessor implements
    				        EnvironmentPostProcessor, ApplicationListener<ApplicationEvent> {
    				    private static final DeferredLog log = new DeferredLog();
    				    @Override
    				    public void postProcessEnvironment(
    				            ConfigurableEnvironment env, SpringApplication app) {
    				        log.error("This should be printed");
    				    }
    				    @Override
    				    public void onApplicationEvent(ApplicationEvent event) {
    				        log.replayTo(MyEnvironmentPostProcessor.class);
    				    }
    				}

    4. カスタマイズした構成を SPI を通じて有効にします1. src/main/resources の下に新しい# を作成します ##META-INF/spring.factories

    File

    2. Configuration<pre class="brush:java;">org.springframework.boot.env.EnvironmentPostProcessor=\ com.huan.springcloud.extensionpoint.environmentpostprocessor.CustomEnvironmentPostProcessor</pre>5. テスト クラスを作成し、定義されたユーザー名属性 値

    @Component
    public class PrintCustomizeEnvironmentProperty implements ApplicationRunner {
    
        private static final Logger log = LoggerFactory.getLogger(PrintCustomizeEnvironmentProperty.class);
        @Value("${username}")
        private String userName;
        @Override
        public void run(ApplicationArguments args) {
            log.info("获取到的 username 的属性值为: {}", userName);
        }
    }

    6. 実行結果SpringBootのEnvironmentPostProcessorの使い方

    #5. 注意事項

    ##1. ログは出力できません

    上記の '

    3. カスタムプロパティを記述し、Spring 環境の SpringBootのEnvironmentPostProcessorの使い方 が提供するソリューションを追加します。

    2. 設定が有効になっていないことを確認する

    EnvironmentPostProcessor の優先順位をチェックして、@Order または Ordered によって返される優先順位の値が正しくないかどうかを確認します。 <li><p>看看别的地方是否实现了 EnvironmentPostProcessor或ApplicationContextInitializer或BeanFactoryPostProcessor或BeanDefinitionRegistryPostProcessor等这些接口,在这个里面修改了 PropertySource的顺序。</p></li> <li><p>理解 Spring 获取获取属性的顺序 参考 2、获取配置属性的优先级</p></li> <h4>3、日志系统如何初始化</h4> <p>如下代码初始化日志系统</p><pre class="brush:java;">org.springframework.boot.context.logging.LoggingApplicationListener</pre>

    以上がSpringBootのEnvironmentPostProcessorの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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