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をパッケージ化して、すぐに通常どおり実行します