Frühling: Wie füge ich einen Wert in ein statisches Feld ein?

87

Mit dieser Klasse

@Component
public class Sample {

    @Value("${my.name}")
    public static String name;


}

Wenn ich es versuche Sample.name, ist es immer 'null'. Also habe ich es versucht.

public class Sample {

    public static String name;

    @PostConstruct
    public void init(){
        name = privateName;
    }

    @Value("${my.name}")
    private String privateName;

    public String getPrivateName() {
        return privateName;
    }

    public void setPrivateName(String privateName) {
        this.privateName = privateName;
    }  

}

Dieser Code funktioniert. Sample.nameist richtig eingestellt. Ist das ein guter Weg oder nicht? Wenn nicht, gibt es einen besseren Weg? Und wie geht das?

Whiteship
quelle
Dies wird nicht gelöst; wenn die statische Variable vor der Objekterstellung verwendet wird. Beispiel: Wenn die statische Variable unter dem statischen Block zum Erstellen der Ressource verwendet wird, wird die Ressource mit null erstellt.
Kanagavelu Sugumar

Antworten:

111

Vor allem public staticnicht finalsind Felder Übel . Die Feder erlaubt aus einem bestimmten Grund keine Injektion in solche Felder.

Ihre Problemumgehung ist gültig, Sie brauchen nicht einmal Getter / Setter, privateFeld ist genug. Versuchen Sie dies auf der anderen Seite:

@Value("${my.name}")
public void setPrivateName(String privateName) {
    Sample.name = privateName;
}  

(arbeitet mit @Autowired/ @Resource). Aber um Ihnen einige konstruktive Ratschläge zu geben: Erstellen Sie eine zweite Klasse mit privateFeld und Getter anstelle von public staticFeld.

Tomasz Nurkiewicz
quelle
9
Könnten Sie mir bitte für "öffentliche statische nicht endgültige Felder sind böse" einige Referenzen geben?
Anderson
7
Nicht endgültig bedeutet, dass Sie den Feldwert ändern können, was für ein statisches Feld die Behandlung der Thread-Parallelität impliziert - auch bekannt als "Pain in the Stack".
Xavier Portebois
Wie verwende ich @Value mit dem statischen Block? Bitte führen Sie uns ... Grüße, Neha
4
Nur zu Ihrer Information: Der obige Code verursacht eine Sonar / Checkstyle-Verletzung (wenn Sie sich über solche Dinge Gedanken machen), da Sie eine Instanzmethode haben, die in ein statisches Feld schreibt.
Neil
Es ist möglich, den endgültigen Aspekt mit einem statischen Setter nachzuahmen, der den Wert nur dann festlegt, wenn er derzeit null ist. Sie erlauben also nur eine Änderung des Feldes. (was natürlich privat gemacht wurde und einen Getter benutzt, um darauf zuzugreifen). Spring kann in seiner Konfigurationsphase eine statische Methode aufrufen (XML oder Annotation).
Walfrat
-1

Spring verwendet die Abhängigkeitsinjektion, um den spezifischen Wert zu füllen, wenn die Annotation @Value gefunden wird. Anstatt den Wert an die Instanzvariable zu übergeben, wird er stattdessen an den impliziten Setter übergeben. Dieser Setter verarbeitet dann die Grundgesamtheit unseres NAME_STATIC-Werts.

    @RestController 
//or if you want to declare some specific use of the properties file then use
//@Configuration
//@PropertySource({"classpath:application-${youeEnvironment}.properties"})
public class PropertyController {

    @Value("${name}")//not necessary
    private String name;//not necessary

    private static String NAME_STATIC;

    @Value("${name}")
    public void setNameStatic(String name){
        PropertyController.NAME_STATIC = name;
    }
}
Vitalii Shramko
quelle