Spring @Value аннотация всегда оценивается как ноль? - PullRequest
29 голосов
/ 09 ноября 2010

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

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 ВСЕГДА имеют значение null ... но в моих контроллерах значение загружается просто отлично. Что дает?

Ответы [ 6 ]

32 голосов
/ 09 ноября 2010

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

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

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

22 голосов
/ 23 августа 2013

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

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

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

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

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

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

Вместо этого в @Controller используйте ...

@Autowired
private MyService service; 

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

@Service
public class MyService implements InitializingBean 

Затем вставьте операторы отладки в ...

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

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

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

3 голосов
/ 09 ноября 2010

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

2 голосов
/ 28 апреля 2012

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

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

0 голосов
/ 11 декабря 2018

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

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

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

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

0 голосов
/ 21 мая 2018

Вы также можете сделать свои свойства 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...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...