エラー記録: @Value の値を取得できない構築メソッド、問題の分析と解決策

エラー記録: @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();
    }
}

3. 結果

ここに画像の説明を挿入

注釈の詳細な説明は次のとおりです. 興味のある友人は、 Spring Framework @PostConstruct 注釈の詳細な説明 - ナゲット (juejin.cn)@PostConstructを参照してください。

おすすめ

転載: blog.csdn.net/qq_57581439/article/details/130389421