SpringBoot入門チュートリアル04-環境の詳細な説明

SpringBoot入門チュートリアル04-環境の詳細な説明

序文

1つはSpringBoot詳細プロファイルポータルを教えてくれます

注意深い学生は実際に中に小さな穴があることに気付くでしょう

たとえば、user.propertiesファイルを変更すると、変更されたコンテンツは次のようになります。

user.name=henry1111
user.age=16

アプリケーションを再起動し、ブラウザを開き、ブラウザを開いてhttp://127.0.0.1:8080/userと入力すると、ブラウザに次のように表示されます。

Henry-16

予想されるhenry1111-16と同じではないのはなぜですか?

別の例を見てみましょう

環境を紹介する

コントローラパッケージの下に、次のコンテンツを含む新しいEnvControllerクラスを作成します

@RestController
public class EnvController {
    
    
    @Autowired
    private Environment env;

    @RequestMapping("/env")
    public String env(){
    
    
        System.out.println(env.getProperty("user.name"));
        System.out.println(env.getProperty("user.age"));

        return env.getProperty("user.name")+"-"+env.getProperty("user.age");
    }
}

次に、アプリケーションを再起動し、ブラウザーを開き、ブラウザーを開いてhttp://127.0.0.1:8080/envと入力すると、ブラウザーに次のように表示されます。

Henry-16

Environmentクラスのインスタンスが格納されているときのSpringコンテナの構成情報、および上記のコンテンツの出力はリクエストhttp://127.0.0.1:8080 / userと一致していますが、の構成とは一致していません。 user.properties、なぜですか?以下で詳しく分析してみましょう。

StandardServletEnvironment

EnvControllerクラスのenv()メソッドにブレークポイントを作成し、http://127.0.0.1:8080 / envをリクエストすると、envの詳細をアイデアで確認できます。
ここに画像の説明を挿入

図に示すように、envは基本的にStandardServletEnvironmentクラスのインスタンスです。コードをトレースし続けると、getPropertyが基本的にpropertySourcesのループを通過することがわかります。現在のpropertySource.getProperty(key)の値がnullの場合、次にトラバースを続行し、値がnullでない場合は、値を返します

PropertySourcesPropertyResolverクラスのgetPropertyメソッドのコードは次のとおりです

@Nullable
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
    
    
    if (this.propertySources != null) {
    
    
        Iterator var4 = this.propertySources.iterator();

        while(var4.hasNext()) {
    
    
            PropertySource<?> propertySource = (PropertySource)var4.next();
            if (this.logger.isTraceEnabled()) {
    
    
                this.logger.trace("Searching for key '" + key + "' in PropertySource '" + propertySource.getName() + "'");
            }

            Object value = propertySource.getProperty(key);
            if (value != null) {
    
    
                if (resolveNestedPlaceholders && value instanceof String) {
    
    
                    value = this.resolveNestedPlaceholders((String)value);
                }

                this.logKeyFound(key, propertySource, value);
                return this.convertValueIfNecessary(value, targetValueType);
            }
        }
    }

    if (this.logger.isTraceEnabled()) {
    
    
        this.logger.trace("Could not find key '" + key + "' in any property source");
    }

    return null;
}

この例では、envのpropertySourcesには11個の要素があり、その最後の要素はカスタム構成ファイルuser.propertiesに対応しています。

この要素のuser.nameとuser.ageは構成ファイルのuser.nameとuser.ageと一致していることがわかりますが、この要素はリストの最後にあります。user.nameが前の要素にある場合は、env.getProperty ( "user。name")は別の値を返します。
ここに画像の説明を挿入
次に、user.nameを見つけようとします。5番目の要素で、systemProperties添え字4が実際にuser.nameを見つけました。
1つずつ見つけるのが面倒なので、コードを使用して環境内にあるキー値を出力し、EnvControllerを変更します。コードは次のとおりです。

@RestController
public class EnvController {
    
    
    @Autowired
    private Environment env;

    @RequestMapping("/env")
    public String env(){
    
    
        StandardServletEnvironment environment = (StandardServletEnvironment) env;
        MutablePropertySources propertySources = environment.getPropertySources();
        Iterator<PropertySource<?>> iterator = propertySources.iterator();
        while (iterator.hasNext()) {
    
    
            PropertySource<?> propertySource = iterator.next();
            if (propertySource instanceof MapPropertySource) {
    
    
                MapPropertySource mapPropertySource = (MapPropertySource) propertySource;
                String[] propertyNames = mapPropertySource.getPropertyNames();
                for (String s : propertyNames) {
    
    
                    System.out.println(s+":"+mapPropertySource.getProperty(s));
                }
            }
        }
        return env.getProperty("user.name")+"-"+env.getProperty("user.age");
    }
}

実行ログは投稿しません。実行して出力を確認できます。

総括する

このセクションを学習した後、Springboot構成ファイルのロードプロセスをより深く理解する必要があります。簡単な要約を次に示します。

  • JVMが起動すると、システムプロパティと環境変数がJVMに渡されます
  • springbootが開始したら、@ Controller、@ Component、@ Configuration、@ Serviceなどのアノテーションをスキャンし、Springコンテナーがインスタンスを管理できることを宣言するクラスを見つけます。
  • これらのクラスに@PropertySourceアノテーションがあるかどうかを確認し、ある場合は、アノテーションで指定された構成ファイルをロードします
  • すべての構成情報を環境インスタンス管理に提供します。構成情報の優先度はソースによって異なります。たとえば、システムプロパティと環境変数の優先度は、ユーザー定義のプロパティファイルの優先度よりも高くなります。
  • 次に、これらのクラスに@ConfigurationPropertiesアノテーションがあるかどうかを判断し、ある場合は、Environmentインスタンスから値を取得し、リフレクションを通じて割り当てます。
  • @Valueアノテーションは@ConfigurationPropertiesアノテーションに似ており、Environmentインスタンスから値を取得し、リフレクションを通じて値を割り当てます。

ピットを踏む

@PropertySource( "")、アイデア開発環境も正常に開始されますが、パッケージ化されてmavenを介して実行されると、java.lang.IllegalArgumentException:不正な形式の\ uxxxxエンコーディングが報告されます。

このエラーに関して、インターネットのほとんどは、構成ファイルに「\」があるか、ファイルパスが中国語であると言っています。長い間チェックした後、「\」と中国語が見つかりませんでした。最初は戸惑いました。 。後で、springboot構成ファイルを注意深く調べました。この記事は、ブートロードプロセスの結果です。

テキストを読んだ後、私たちはそれを知っています

  • @PropertySourceアノテーションがSpringコンテナによって管理されるクラス上にある限り、どのクラスが本質的に同じであっても、通常、対応するJavaBean構成クラスに書き込みます。
  • @PropertySource( "")はファイル名を指定していません、このアノテーションは役に立ちません
  • @PropertySource( "")アノテーションを削除し、Mavenをパッケージ化して、すぐに通常どおり実行します

おすすめ

転載: blog.csdn.net/l229568441/article/details/106959336