エラー記録: @Value の値を取得できない構築メソッド、問題の分析と解決策
コンストラクターでプロパティを初期化する必要がある場合があります. 古いプロジェクトでは I/O ストリームを使用して構成ファイルの値を取得していました. 現在の構成をオンラインに変換し, Apollo を使用して値を取得します. Apollo の取得した値はSpring にカプセル化されています。コンテナーでは、Spring コンテナーの構成値を使用する必要があります。
構成を取得する最も簡単な方法は @Value アノテーションを使用することですが、古いプロジェクトでは、構成メソッドを使用して Kafka の構成情報を初期化していました. ここでは、プロジェクトの初期化でエラーが報告されます. デバッグ後に発見されました取得した構成ファイルの情報が null であり、バグが発生する可能性があります。
なぜなら:
对象被Spring容器接管之前会调用构造函数构造对象,导致注解失效,构造函数执行完成被Spring容器接管之后才会调用@Value注解将配置注入对应的属性当中
ここに解決策があります
1.Spring
コンテナがオブジェクトを引き継ぐときの実行シーケンスを表示する
1.A.java
クラス
@Component
public class A {
public A(){
System.out.println("构造函数");
}
public void Test(){
System.out.println("Test");
}
}
2.テストクラスATest.java
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}
3. 結果
2.構成ファイルに対応する値がないかどうか、または注釈が@Value
有効になっていないかどうかを確認します
1.構成ファイルには2つの値があります
num=1
url="http://localhost:8080/test"
2.A.java
クラスを変更し、共通メソッドを確認する
@SpringBootTest
public class ATest {
@Value("${num}")
private int num;
@Value("${url}")
private String url;
@Value("${url:测试}")
private String url2;
@Value("${url3:测试默认值}")
private String url3;
@Autowired
private A a;
public A(){
System.out.println("===========构造函数================");
System.err.println(num);
System.err.println(url);
System.err.println(url2);
System.err.println(url3);
}
public void Test(){
System.out.println("===========Test方法================");
System.err.println(num);
System.err.println(url);
System.err.println(url2);
System.err.println(url3);
}
}
2.テスト クラスATest.java
の Test メソッドを実行します。
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}
3.結果が@Value
反映されない、もちろん@ConfigurationProperties
反映されない
(1)、@Value
注意事項
(2)@ConfigurationProperties
注: クラス全体を直接見るためにここにブレークポイントを作成しましたAnimal.java
. このクラスはこの記事には入れませんでした. 必要ありません. とにかく大丈夫です.
4 結論
int
プリミティブ データ型のデフォルト値はですが0
、クラスString
であるため、デフォルト値はnull
url3
,url2
これら 2 つのプロパティの@Value
注釈にデフォルト値を追加しました.@Value
それが有効になり、設定ファイルに値が見つからない場合は、デフォルト値が返されますここで 4 つのプロパティによって返される基本的なデフォルト値は、コンストラクターが実行されたときに
Spring
オブジェクトが引き継がれず、@Value
アノテーションがまったく有効にならないことを示しています。
3. 解決策:@PostConstruct
注釈を使用する
1.A.java
変換
@Component
public class A {
@Value("${num}")
private int num;
@Value("${url}")
private String url;
@Value("${url:测试}")
private String url2;
@Value("${url3:测试默认值}")
private String url3;
public A(){
System.out.println("===========构造函数================");
System.err.println(num);
System.err.println(url);
System.err.println(url2);
System.err.println(url3);
}
public void Test(){
System.out.println("===========Test方法================");
System.err.println(num);
System.err.println(url);
System.err.println(url2);
System.err.println(url3);
}
@PostConstruct
public void initField(){
System.out.println("===========构造函数结束之后自动执行================");
System.err.println(num);
System.err.println(url);
System.err.println(url2);
System.err.println(url3);
}
}
2. テストクラスを実行するATest.java
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}