Spring аннотация @Value в классе @Controller, не оценивающая значение внутри файла свойств
Я новичок в Spring и пытаюсь ввести строку со значением, используя аннотацию @Value("${loginpage.message}")
внутри контроллера, аннотированную аннотацией @Controller
, и значение моей строки оценивается как строка "${loginpage.message}"
, а не то, что находится внутри моего файла свойств.
Ниже мой контроллер с строкой 'message', которую я хочу ввести.
@Controller
public class LoginController extends BaseController {
@Value("${loginpage.message}")
private String message;
@RequestMapping("/")
public String goToLoginPage(Model model) {
model.addAttribute("message", message);
return "/login";
}
}
Мой контекст приложения выглядит следующим образом:
<context:property-placeholder location="classpath:properties/application.properties" />
<context:annotation-config />
<context:component-scan base-package="com.me.application" />
В моем файле свойств есть строка:
loginpage.message=this is a test message
Spring должен подбирать значение в какой-то момент, потому что всякий раз, когда я изменяю @Value("${loginpage.message}")
на значение, не содержащееся в файле свойств, например @Value("${notInPropertiesFile}")
, я получаю исключение.
Ответы
Ответ 1
Кажется, что вопрос уже задан Spring 3.0.5 не оценивает аннотацию @Value от свойств
Разница между контекстами приложений root и сервлетов является одним из главных источников путаницы в Spring, см. Разница между applicationContext.xml и spring -servlet.xml в Spring Framework
От @Value
javadoc:
Обратите внимание, что фактическая обработка аннотации @Value выполняется с помощью BeanPostProcessor
Из Spring документация:
Интерфейсы BeanPostProcessor привязаны к контейнеру. Это актуально только в том случае, если вы используете иерархии контейнеров. Если вы определяете BeanPostProcessor в одном контейнере, он будет выполнять свою работу только с beans в этом контейнере. beans, которые определены в одном контейнере, не обрабатываются BeanPostProcessor в другом контейнере, даже если оба контейнера являются частью одной и той же иерархии.
Ответ 2
У меня такая же проблема с Spring 3. Она не работает внутри контроллеров.
Чтобы исправить проблему, я создал другой bean с @Service и ввел его в контроллер.
Это работало для меня. Надеюсь, это будет полезно для кого-то, поскольку я провел весь день, чтобы понять это.
Ответ 3
Вы можете @Autowire Environment
, а затем environment.getProperty("name")
.
См. fooobar.com/questions/110215/...
Ответ 4
Вам нужно использовать PropertySourcePlaceHolder, если вы используете аннотацию @Value, потому что она может извлечь значение из файла свойств. Если вы используете базу java config, вам нужно создать bean, как этот
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
Или, если вы используете xml, тогда объявите bean соответственно.
Ответ 5
У меня была аналогичная проблема в моем проекте spring, но в частности spring BATCH one. Сначала я построил свою конфигурацию ниже
@Configuration
public class BatchConfig
{
@Bean
public Job job(@Autowired Step stepMulti, @Autowired Step stepMultiDiff, @Autowired Step stepMultiPolling
){
Job job = jobBuilders.get("job")
.start(init0())
.on("POLLING").to(stepMultiPolling)
.from(init0()).on("*").to(stepMulti).next(stepMultiDiff).end()
.build();
return job;
}
@Bean
public Step init0(){
return stepBuilders.get("init0")
.tasklet(new MyDecider())
.build();
}
...
}
с MyDecider в ближайшее время, как показано ниже
public class MyDecider implements StepExecutionListener , Tasklet{
@Autowired ThreadPoolTaskScheduler taskScheduler;
@Value("${read.chunk.size}") private Integer pagesize;
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
return RepeatStatus.FINISHED;
}
@Override
public ExitStatus afterStep(StepExecution exe) {
String type = exe.getJobParameters().getString("mode");
log.info("SPRING BATCH props:");
log.info(" READ chunk size: {}", pagesize);
if (StringUtils.equals(type, "send")) {
log.info("MODE batch SENDING...");
if (taskScheduler !=null) taskScheduler.shutdown();
else log.info(" Not able to stop scheduler (is null)");
return new ExitStatus("SEND");
} else {
log.info("MODE batch POLLING...");
return new ExitStatus("POLLING");
}
}
Но таким образом не был подключен ни один TaskScheduler, ни встраивание не было выполнено; оба null. Благодаря ответу Бориса, после некоторых попыток я сменил BatchConfig как ниже отлично работающий
...
@Bean
public Step init0(){
return stepBuilders.get("init0")
.tasklet(decider())
.build();
}
@Bean
public Tasklet decider() {
return new MyDecider();
}
...
Причина: построение MyDecider ближе к аннотации Bean в BatchConfig (один из decider()), make spring понять, что MyDecider должен быть введен правильно, со значениями, найденными в значениях application.property и проводных с использованием TaskScheduler (потому что я попробовал также активировать SpringScheduler, но я хотел отбросить его, если опция запуска jar была "send" ).
ПРИМЕЧАНИЕ: с опционным режимом = "отправить" spring пакетное задание переходит к stepMulti, а не stepMultiPolling, поскольку статус выхода MyDecider был SEND, а не POLLING; но это только объяснение из этой темы, поэтому я пропущу дальнейшие подробности.
Надеюсь, что этот пакет spring может быть полезен для кого-то!