Spring аннотация @Value всегда оценивается как null?

Итак, у меня есть простой файл свойств со следующими данными:

my.value=123
another.value=hello world

Этот файл свойств загружается с помощью PropertyPlaceHolderConfigurer, который ссылается на файл свойств выше.

У меня есть следующий класс, для которого я пытаюсь загрузить эти свойства так:

public class Config
{
    @Value("${my.value}")
    private String mValue;

    @Value("${another.value}")
    private String mAnotherValue;

    // More below...
}

Проблема в том, что mValue и mAnotherValue являются ALWAYS null... еще в моих контроллерах значение очень просто загружается. Что дает?

Ответы

Ответ 1

Если экземпляры Config создаются вручную через new, тогда Spring не участвует, поэтому аннотации будут проигнорированы.

Если вы не можете изменить свой код, чтобы make Spring создавал экземпляр bean (возможно, с помощью prototype -scoped bean), тогда другой вариант - использовать Spring загрузку загрузчика классов нагрузки функциональность (см. docs). Это некоторый низкоуровневый АОП, который позволяет создавать объекты, как обычно, но Spring передаст их через контекст приложения, чтобы подключить их, настроить, инициализировать и т.д.

Однако он не работает на всех платформах, поэтому прочитайте приведенную выше ссылку на документацию, чтобы узнать, будет ли это работать для вас.

Ответ 2

У меня были похожие проблемы, но был новичком Spring. Я пытался загрузить свойства в @Service и пытался использовать @Value для получения значения свойства с помощью...

@Autowired
public @Value("#{myProperties['myValue']}") String myValue;

Я целый день пробовал различные комбинации аннотаций, но всегда возвращал null. В конечном итоге ответ, как всегда, очевидно после факта.

1) убедитесь, что Spring сканирует ваш класс для аннотаций, включив в себя пакет hierachy В вашем servlet.xml(он будет сканировать все ниже базового значения, которое вы вставляете.

2) Убедитесь, что вы НЕ 'new'ing класс, который вы только что сказали Spring, чтобы посмотреть. Вместо этого вы используете @Autowire в классе @Controller.

Все в Spring является синглтоном, а то, что происходило, было Spring загружено значениями в его Singleton, тогда у меня был "новый" другой экземпляр класса, который не содержал вновь загруженных значений, всегда null.

Вместо использования @Controller...

@Autowired
private MyService service; 

Debugging... Одна вещь, которую я сделал, чтобы найти это, заключается в том, чтобы продлить мою службу следующим образом...

@Service
public class MyService implements InitializingBean 

Затем вставьте отладочные инструкции в...

@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
LOGGER.debug("property myValue:" + myValue);        
}

Здесь я мог видеть, что значение устанавливается при инициализации, а позже, когда я напечатал его в методе, оно было нулевым, поэтому для меня это было хорошей подсказкой, что это был не тот же экземпляр.

Еще одна подсказка к этой ошибке заключалась в том, что Tomcat жаловался на тайм-ауты, пытаясь прочитать из Socket с Unable для разбора HTTPheader... Это было потому, что Spring создал экземпляр службы, и у меня тоже был, выполняя настоящую работу, а Spring выбрал время для своего экземпляра.

Ответ 3

Поскольку он работает с @Controller, кажется, вы сами создаете Config. Пусть Spring создает экземпляр.

Ответ 4

Добавьте <context:spring-configured /> к вашему файлу контекста приложения.

Затем добавьте аннотацию @Configurable в класс Config.

Ответ 5

Вы также можете сделать свои свойства private, убедиться, что ваш класс - это bean-компонент Spring, используя аннотации @Service или @Component, так что он всегда создается, и, наконец, добавить методы установки с аннотацией @Value. Это гарантирует, что вашим свойствам будут присвоены значения, указанные в ваших конфигурационных файлах application.properties или yml.

@Service
public class Config {
    private static String mValue;

    private static String mAnotherValue;

    @Value("${my.value}")    
    public void setmValue(String mValue) {
    this.mValue = mValue;}

    @Value("${another.value}")
    public void setmAnotherValue(String mAnotherValue) {
    this.mAnotherValue = mAnotherValue;}

    //rest of your code...
}

Ответ 6

Смотрите мой ответ здесь.

Я столкнулся с теми же симптомами (@Value -annotated равны null), но с другой основной проблемой:

import com.google.api.client.util.Value;

Убедитесь, что вы импортируете правильный @Value аннотации @Value ! Особенно в связи с удобством IDE в настоящее время, это ОЧЕНЬ простая ошибка (я использую IntelliJ, и если вы автоматически импортируете слишком быстро, не читая ЧТО вы автоматически импортируете, вы можете потратить несколько часов, как я).