Spring: Comment injecter une valeur dans un champ statique?

90

Avec cette classe

@Component
public class Sample {

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


}

Si j'essaye Sample.name, c'est toujours «nul». Alors j'ai essayé ça.

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

}

Ce code fonctionne. Sample.nameest correctement réglé. Est-ce bon ou pas? Sinon, y a-t-il quelque chose de plus bon? Et comment le faire?

Whiteship
la source
Cela ne résoudra pas; si la variable statique est utilisée avant la création de l'objet. par exemple) si la variable statique est utilisée sous un bloc statique pour construire la ressource, alors la ressource sera construite avec null.
Kanagavelu Sugumar

Réponses:

115

Tout d'abord, les public staticnon- finalchamps sont mauvais . Spring ne permet pas d'injecter de tels champs pour une raison.

Votre solution de contournement est valide, vous n'avez même pas besoin de getter / setter, le privatechamp suffit. D'autre part, essayez ceci:

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

(fonctionne avec @Autowired/ @Resource). Mais pour vous donner quelques conseils constructifs: créez une deuxième classe avec privatefield et getter au lieu de public staticfield.

Tomasz Nurkiewicz
la source
9
Pour "les champs non finaux statiques publics sont mauvais", pourriez-vous me donner quelques références?
Anderson
7
Non-final signifie que vous pouvez modifier la valeur du champ, ce qui, pour un champ statique, implique de gérer la concurrence des threads - c'est-à-dire la douleur dans la pile.
Xavier Portebois
Comment utiliser @Value avec un bloc statique? Veuillez nous guider ... Regards, Neha
4
Juste pour info: le code ci-dessus provoquera une violation Sonar / Checkstyle (si vous vous souciez de ce genre de chose) car vous avez une méthode d'instance qui écrit dans un champ statique.
Neil
Il est possible d'imiter l'aspect final en utilisant un setter statique qui ne définira la valeur que si elle est actuellement nulle. Vous n'autorisez donc qu'une seule modification du champ. (qui bien sûr a été rendu privé et utilise un getter pour y accéder). Spring peut appeler une méthode statique dans sa phase de configuration (XML ou annotation).
Walfrat
0

Ceci est mon exemple de code pour charger la variable statique

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;
    }
}
Thành Nguyễn
la source
-2

Spring utilise l'injection de dépendances pour renseigner la valeur spécifique lorsqu'il trouve l'annotation @Value. Cependant, au lieu de transmettre la valeur à la variable d'instance, elle est transmise au setter implicite à la place. Ce setter gère ensuite la population de notre valeur 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;
    }
}
Vitalii Shramko
la source