Spring @Value Annotation wird immer als null ausgewertet?
Lesezeit: 6 Minuten
Ich habe also eine einfache Eigenschaftendatei mit den folgenden Einträgen:
my.value=123
another.value=hello world
Diese Eigenschaftendatei wird mit einem geladen PropertyPlaceHolderConfigurerdie auf die obige Eigenschaftendatei verweist.
Ich habe die folgende Klasse, für die ich versuche, diese Eigenschaften so zu laden:
public class Config
{
@Value("${my.value}")
private String mValue;
@Value("${another.value}")
private String mAnotherValue;
// More below...
}
Das Problem ist, dass, mValue Und mAnotherValue sind IMMER null … aber in meinen Controllern wird der Wert gut geladen. Was gibt?
Ist die Config-Klasse als Spring Bean definiert?
– Raghuram
9. November 2010 um 4:28 Uhr
NEIN? Wie würde ich das mit Anmerkungen machen?
– Polaris878
9. November 2010 um 4:39 Uhr
Ich habe versucht, “@Component” und “@Controller” für die Klasse zu verwenden, und beides hat nicht funktioniert
– Polaris878
9. November 2010 um 4:57 Uhr
Wie es funktioniert Controller Dann? Was ist an Ihrem Controller anders?
– Adel Ansari
9. November 2010 um 4:58 Uhr
Das ist es, was mich so verwirrt … die Config-Klasse befindet sich im selben Paket und alles … der einzige Unterschied besteht darin, dass ich mit meinem Controller, der funktioniert, tatsächlich eine Anforderungszuordnung habe.
– Polaris878
9. November 2010 um 5:00 Uhr
Wenn Instanzen von Config werden manuell über instanziiert newdann mischt sich Spring nicht ein, und daher werden die Anmerkungen ignoriert.
Wenn Sie Ihren Code nicht ändern können, damit Spring die Bean instanziiert (möglicherweise mit einer prototype-scoped Bean), dann besteht die andere Option darin, Springs Ladezeit-Classloader-Weaving-Funktionalität zu verwenden (siehe Dokumente). Dies ist ein Low-Level-AOP, mit dem Sie Objekte wie gewohnt instanziieren können, aber Spring leitet sie durch den Anwendungskontext, um sie zu verdrahten, zu konfigurieren, zu initialisieren usw.
Es funktioniert jedoch nicht auf allen Plattformen, also lesen Sie den obigen Dokumentationslink, um zu sehen, ob es für Sie funktioniert.
Hey Skaffman, danke für den Rat … Das Problem ist, dass ich instanziiere Config von einer JSP. Ich bin mir nicht sicher, ob ich da einen Weg finden kann? Vielleicht durch die Verwendung einer Art Fabrik?
– Polaris878
9. November 2010 um 16:12 Uhr
@ Polaris878: Mein Vorschlag sollte immer noch für JSP-instanziierte Objekte funktionieren (jedes beliebige Objekt, das über Reflektion instanziiert wird).
– Skaffmann
9. November 2010 um 16:50 Uhr
+1. Ich nehme an, in diesem Detail über Spring Bescheid zu wissen. Habe es jahrelang nicht angerührt. Blöder Arbeitsplatz.
– Adel Ansari
10. November 2010 um 2:25 Uhr
+1 Oh je … das rettet mich! Versuchte, Eigenschaftsdateien zu lesen, und war sich nicht sicher, warum @Value null gab
– Vladtn
24. Januar 2013 um 13:13 Uhr
Danke, das war es. Ich habe versucht, ein neues Objekt zu instanziieren, anstatt die Klasse automatisch zu verdrahten und Spring die Arbeit erledigen zu lassen.
– rudyg123
7. April 2022 um 22:57 Uhr
Ich hatte ähnliche Probleme, war aber ein Neuling in Spring. Ich habe versucht, Eigenschaften in einen @Service zu laden, und versucht, @Value zu verwenden, um den Eigenschaftswert abzurufen mit …
@Autowired
public @Value("#{myProperties['myValue']}") String myValue;
Ich verbringe einen ganzen Tag damit, verschiedene Kombinationen von Anmerkungen auszuprobieren, aber es wurde immer null zurückgegeben. Am Ende ist die Antwort wie immer im Nachhinein offensichtlich.
1) Stellen Sie sicher, dass Spring Ihre Klasse nach Anmerkungen durchsucht, indem Sie die Pakethierarchie in Ihre servlet.xml aufnehmen (es wird alles unter dem von Ihnen eingefügten Basiswert scannen.
2) Stellen Sie sicher, dass Sie die Klasse, die Sie Spring gerade angeschaut haben, NICHT „neu“ machen. Stattdessen verwenden Sie @Autowire in der Klasse @Controller.
Alles in Spring ist ein Singleton, und was passierte, war, dass Spring die Werte in seinen Singleton geladen hatte, dann hatte ich eine andere Instanz der Klasse „neu“ erstellt, die die neu geladenen Werte nicht enthielt, sodass sie immer null war.
Verwenden Sie stattdessen im @Controller …
@Autowired
private MyService service;
Debugging … Eine Sache, die ich getan habe, um dies zu finden, war, meinen Dienst wie folgt zu erweitern …
@Service
public class MyService implements InitializingBean
Geben Sie dann Debug-Anweisungen ein in …
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
LOGGER.debug("property myValue:" + myValue);
}
Hier konnte ich sehen, dass der Wert bei der Initialisierung gesetzt wurde, und später, als ich ihn in einer Methode druckte, war er null, also war dies ein guter Hinweis für mich, dass es nicht dieselbe Instanz war.
Ein weiterer Hinweis auf diesen Fehler war, dass Tomcat sich über Timeouts beschwerte, die versuchten, aus dem Socket zu lesen, mit Unable to parse HTTPheader … Dies lag daran, dass Spring eine Instanz des Dienstes erstellt hatte, und ich auch, also erledigte meine Instanz die eigentliche Arbeit. und Spring war auf seiner Instanz zeitlich abgelaufen.
was ist hier myProperties. könnten Sie bitte erklären.
– SYMA
3. Juli 2018 um 15:44 Uhr
In meinem Fall war es Nummer 2. Wechsel von Deklaration als new Zu @Autowired mein Problem gelöst.
– JackTheKnife
12. März 2019 um 17:31 Uhr
Ich kann bestätigen, dass die Eigenschaften in meinem festgelegt werden @ServiceKlasse, aber wenn ich versuche, auf diese Felder zu verweisen, indem ich sie über in eine andere Klasse ziehe @Autowired private MyService myservice, sind diese Felder jetzt null. Warum passiert das?
– Fudge
29. März um 4:10 Uhr
scottysseus
Siehe meine Antwort hier.
Ich hatte die gleichen Symptome (@Value-beschriftete Felder werden null), aber mit einem anderen zugrunde liegenden Problem:
import com.google.api.client.util.Value;
Stellen Sie sicher, dass Sie die richtige importieren @Value Anmerkungsklasse! Besonders mit der Bequemlichkeit von IDEs heutzutage ist dies ein SEHR leicht zu machender Fehler (ich verwende IntelliJ, und wenn Sie zu schnell automatisch importieren, ohne zu lesen, WAS Sie automatisch importieren, können Sie wie ich ein paar Stunden verschwenden).
Toller Fund! In meinem Fall habe ich die regulären Spring-Boot-Abhängigkeiten mit dem Plugin “org.springframework.boot” überschattet
– diman82
3. Juni 2020 um 13:32 Uhr
Was ist die richtige Anmerkung? Dies sollte in einer Antwort angegeben werden
– Notacorn
2. März 2022 um 0:06 Uhr
Ich habe der Antwort den richtigen Import hinzugefügt
– Scottysseus
2. März 2022 um 15:25 Uhr
Als seine Arbeit mit @Controlleres scheint, dass Sie instanziieren Config du selbst. Lassen Sie den Frühling es instanziieren.
Keiv
Sie können auch Ihre Eigenschaften machen privatestellen Sie sicher, dass Ihre Klasse eine Spring Bean verwendet @Service oder @Component Anmerkungen, damit es immer instanziiert wird, und fügen Sie schließlich mit kommentierte Setter-Methoden hinzu @Value . Dadurch wird sichergestellt, dass Ihren Eigenschaften die in Ihren application.properties- oder yml-Konfigurationsdateien angegebenen Werte zugewiesen werden.
@Service
public class Config {
private static String myProperty;
private static String myOtherProperty;
@Value("${my.value}")
public void setMyProperty(String myValue) {
this.myProperty = myValue;}
@Value("${other.value}")
public void setMyOtherProperty(String otherValue) {
this.myOtherProperty = otherValue;}
//rest of your code...
}
Kabale
Hinzufügen <context:spring-configured /> zu Ihrer Anwendungskontextdatei.
Fügen Sie dann die hinzu @Configurable Anmerkung zu Config Klasse.
JoSste
In meinem Fall in meinem Komponententest ist executeScenarioRequest immer null
@RunWith(SpringRunner.class)
@ExtendWith(MockitoExtension.class)
class ScenarioServiceTestOld {
@Value("classpath:scenario/SampleScenario.json")
Resource executeScenarioRequest;
Ändern @ExtendWith(MockitoExtension.class) Zu @ExtendWith(SpringExtension.class)
14498300cookie-checkSpring @Value Annotation wird immer als null ausgewertet?yes
Ist die Config-Klasse als Spring Bean definiert?
– Raghuram
9. November 2010 um 4:28 Uhr
NEIN? Wie würde ich das mit Anmerkungen machen?
– Polaris878
9. November 2010 um 4:39 Uhr
Ich habe versucht, “@Component” und “@Controller” für die Klasse zu verwenden, und beides hat nicht funktioniert
– Polaris878
9. November 2010 um 4:57 Uhr
Wie es funktioniert
Controller
Dann? Was ist an Ihrem Controller anders?– Adel Ansari
9. November 2010 um 4:58 Uhr
Das ist es, was mich so verwirrt … die Config-Klasse befindet sich im selben Paket und alles … der einzige Unterschied besteht darin, dass ich mit meinem Controller, der funktioniert, tatsächlich eine Anforderungszuordnung habe.
– Polaris878
9. November 2010 um 5:00 Uhr