Primavera: come iniettare un valore in un campo statico?


91

Con questa classe

@Component
public class Sample {

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


}

Se provo Sample.name, è sempre "null". Quindi ho provato questo.

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;
    }  

}

Questo codice funziona. Sample.nameè impostato correttamente. È un buon modo o no? In caso contrario, c'è qualcosa di più buono? E come si fa?


1
Questo non risolverà; se la variabile statica viene utilizzata prima della creazione dell'oggetto. ad esempio) se la variabile statica viene utilizzata nel blocco statico per costruire la risorsa, la risorsa verrà costruita con null.
Kanagavelu Sugumar

Risposte:


116

Prima di tutto, i public staticnon- finalcampi sono il male . La primavera non consente l'iniezione in tali campi per un motivo.

La tua soluzione alternativa è valida, non hai nemmeno bisogno di getter / setter, il privatecampo è sufficiente. D'altra parte prova questo:

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

(funziona con @Autowired/ @Resource). Ma per darti qualche consiglio costruttivo: crea una seconda classe con privatefield e getter invece che public staticfield.


9
Per "public static non-final fields are evil", potresti darmi qualche riferimento?
Anderson

7
Non finale significa che puoi modificare il valore del campo, che, per un campo statico, implica la gestione della concorrenza dei thread, ovvero il problema dello stack.
Xavier Portebois

Come usare @Value con il blocco statico? Gentilmente guidaci ... Saluti, Neha

4
Cordiali saluti: il codice sopra causerà una violazione del sonar / stile di controllo (se sei infastidito da quel tipo di cose) poiché hai un metodo di istanza che scrive in un campo statico.
Neil

È possibile imitare l'aspetto finale utilizzando un setter statico che imposterà il valore solo se è attualmente nullo. Quindi consenti solo una modifica del campo. (che ovviamente è stato reso privato e usa un getter per accedervi). Spring può chiamare il metodo statico nella sua fase di configurazione (XML o Annotation).
Walfrat

0

Questo è il mio codice di esempio per caricare la variabile statica

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class OnelinkConfig {
    public static int MODULE_CODE;
    public static int DEFAULT_PAGE;
    public static int DEFAULT_SIZE;

    @Autowired
    public void loadOnelinkConfig(@Value("${onelink.config.exception.module.code}") int code,
            @Value("${onelink.config.default.page}") int page, @Value("${onelink.config.default.size}") int size) {
        MODULE_CODE = code;
        DEFAULT_PAGE = page;
        DEFAULT_SIZE = size;
    }
}

-2

Spring utilizza l'inserimento delle dipendenze per popolare il valore specifico quando trova l'annotazione @Value. Tuttavia, invece di passare il valore alla variabile di istanza, viene invece consegnato al setter implicito. Questo setter gestisce quindi la popolazione del nostro valore NAME_STATIC.

    @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;
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.