Fehlerprotokoll: Die Konstruktionsmethode kann den Wert von @Wert, Problemanalyse und Lösung nicht erhalten
Manchmal müssen wir Eigenschaften im Konstruktor initialisieren.Das alte Projekt verwendete E/A-Streams, um den Wert der Konfigurationsdatei zu erhalten.Die aktuelle Konfiguration wird in Online konvertiert, und Apollo wird verwendet, um den Wert zu erhalten.Weil der erhaltene Wert von Apollo ist in Spring gekapselt. Im Container müssen wir den Konfigurationswert im Spring-Container verwenden
Der einfachste Weg, die Konfiguration zu erhalten, ist die Verwendung der Annotation @Value, aber im alten Projekt wird die Konstruktionsmethode verwendet, um die Konfigurationsinformationen von Kafka zu initialisieren.Hier meldet die Projektinitialisierung einen Fehler.Nach dem Debuggen wird er gefunden dass die erhaltenen Konfigurationsdateiinformationen null sind, was zu einem Fehler führt.
Weil:
对象被Spring容器接管之前会调用构造函数构造对象,导致注解失效,构造函数执行完成被Spring容器接管之后才会调用@Value注解将配置注入对应的属性当中
Hier ist die Lösung
1. Zeigen Sie Spring
die Ausführungsreihenfolge an, wenn der Container das Objekt übernimmt
1. A.java
Klasse
@Component
public class A {
public A(){
System.out.println("构造函数");
}
public void Test(){
System.out.println("Test");
}
}
2. TestklasseATest.java
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}
3. Ergebnisse
2. Prüfen Sie, ob die Konfigurationsdatei keinen entsprechenden Wert hat oder die Anmerkung @Value
nicht greift
1. Es gibt zwei Werte in der Konfigurationsdatei
num=1
url="http://localhost:8080/test"
2. Modifizieren Sie A.java
die Klasse und sehen Sie sich die gemeinsame Methode an
@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. Führen Sie ATest.java
die Test-Methode der Testklasse aus
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}
3. Das Ergebnis @Value
wird nicht wirksam und wird natürlich @ConfigurationProperties
nicht wirksam
(1), @Value
Anmerkungen
(2) @ConfigurationProperties
Beachten Sie, dass ich hier einen Haltepunkt gesetzt habe, um direkt auf die gesamte Animal.java
Klasse zu schauen. Ich habe diese Klasse nicht in diesen Artikel eingefügt. Es ist nicht notwendig. Wie auch immer, es ist in Ordnung.
4. Fazit
Da
int
der Standardwert eines primitiven Datentyps0
,String
aber eine Klasse ist, ist der Standardwertnull
url3
, habe ich den Anmerkungenurl2
in diesen beiden Eigenschaften@Value
Standardwerte hinzugefügt.Wenn@Value
es wirksam wird und der Wert nicht in der Konfigurationsdatei gefunden werden kann, wird der Standardwert zurückgegebenDie von den vier Eigenschaften zurückgegebenen grundlegenden Standardwerte weisen hier darauf hin, dass beim Ausführen des Konstruktors
Spring
das Objekt nicht übernommen wird, was dazu führt, dass@Value
die Annotation überhaupt nicht wirksam wird.
3. Lösung: @PostConstruct
Anmerkungen verwenden
1. A.java
Umwandlung
@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. Führen Sie die Testklasse ausATest.java
@SpringBootTest
public class ATest {
@Autowired
private A a;
@Test
public void TestA(){
a.Test();
}
}