Spring: как ввести значение в статическое поле?

90

С этим классом

@Component
public class Sample {

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


}

Если я попробую Sample.name, он всегда будет нулевым. Итак, я попробовал это.

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

}

Этот код работает. Sample.nameустановлен правильно. Это хороший способ или нет? Если нет, есть ли более хороший способ? И как это сделать?

Whiteship
источник
Это не решит; если статическая переменная используется до создания объекта. например) если статическая переменная используется в статическом блоке для создания ресурса, то ресурс будет создан с нулевым значением.
Канагавелу Сугумар

Ответы:

115

Во-первых, public staticнеполя final- зло . Spring по какой-то причине не позволяет делать инъекции в такие поля.

Ваш обходной путь действителен, вам даже не нужен геттер / сеттер, privateдостаточно поля. С другой стороны, попробуйте следующее:

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

(работает с @Autowired/ @Resource). Но чтобы дать вам конструктивный совет: создайте второй класс с privateполем и получателем вместо public staticполя.

Томаш Нуркевич
источник
9
Не могли бы вы дать мне несколько ссылок для «публичных статических неокончательных полей»?
Андерсон
7
Неокончательный означает, что вы можете изменить значение поля, что для статического поля подразумевает обработку параллелизма потоков - иначе говоря, боль в стеке.
Xavier Portebois 09
Как использовать @Value со статическим блоком? Пожалуйста,
4
Просто к сведению: приведенный выше код вызовет нарушение Sonar / Checkstyle (если вас беспокоят такие вещи), поскольку у вас есть метод экземпляра, записывающий в статическое поле.
Нил
Можно имитировать последний аспект, используя статический сеттер, который будет устанавливать значение только в том случае, если оно в настоящее время равно нулю. Таким образом, вы разрешаете только одно изменение поля. (который, конечно, стал закрытым и для доступа к нему используется геттер). Spring может вызывать статический метод на этапе своей конфигурации (XML или аннотации).
Walfrat
0

Это мой пример кода для загрузки статической переменной

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 Nguyn
источник
-2

Spring использует внедрение зависимостей для заполнения определенного значения при обнаружении аннотации @Value. Однако вместо того, чтобы передать значение переменной экземпляра, оно передается неявному установщику. Затем этот установщик обрабатывает заполнение нашего значения 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;
    }
}
Виталий Шрамко
источник