@Controller 类中的 Spring @Value 注释不评估属性文件中的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11890544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @Value annotation in @Controller class not evaluating to value inside properties file
提问by Chris
I am new to Spring and trying to inject a string with a value using the @Value("${loginpage.message}")annotation inside of a controller annotated with the @Controllerannotation and the value of my string is being evaluated as the string "${loginpage.message}"and not what is inside my properties file.
我是 Spring 的新手,并尝试使用带有@Value("${loginpage.message}")注释的控制器内部的注释注入一个带有值的字符串,@Controller并且我的字符串的值被评估为字符串,"${loginpage.message}"而不是我的属性文件中的内容。
Below is my controller with the string 'message' that I want to inject.
下面是我的控制器,其中包含我要注入的字符串“消息”。
@Controller
public class LoginController extends BaseController {
@Value("${loginpage.message}")
private String message;
@RequestMapping("/")
public String goToLoginPage(Model model) {
model.addAttribute("message", message);
return "/login";
}
}
My application context looks like this:
我的应用程序上下文如下所示:
<context:property-placeholder location="classpath:properties/application.properties" />
<context:annotation-config />
<context:component-scan base-package="com.me.application" />
My properties file has the line:
我的属性文件有一行:
loginpage.message=this is a test message
Spring must be picking up the value at some point because whenever I change @Value("${loginpage.message}")to a value not in the properties file like @Value("${notInPropertiesFile}"), I get an exception.
Spring 必须在某个时候获取该值,因为每当我更改@Value("${loginpage.message}")为不在属性文件中的值时,例如@Value("${notInPropertiesFile}"),我都会收到异常。
回答by Boris Treukhov
It seems that the question has been already asked Spring 3.0.5 doesn't evaluate @Value annotation from properties
似乎已经问过这个问题Spring 3.0.5 没有从属性中评估 @Value 注释
The difference between web app root and servlet application contexts is one of the top sources of confusion in Spring, see Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
Web 应用程序根和 servlet 应用程序上下文之间的差异是 Spring 中最容易混淆的来源之一,请参阅 Spring Framework 中 applicationContext.xml 和 spring-servlet.xml 之间的差异
From @Valuejavadoc :
从@Valuejavadoc :
Note that actual processing of the @Value annotation is performed by a BeanPostProcessor
注意@Value注解的实际处理是由一个BeanPostProcessor执行的
BeanPostProcessor interfaces are scoped per-container. This is only relevant if you are using container hierarchies. If you define a BeanPostProcessor in one container, it will only do its work on the beans in that container. Beans that are defined in one container are not post-processed by a BeanPostProcessor in another container, even if both containers are part of the same hierarchy.
BeanPostProcessor 接口的范围是每个容器的。这仅在您使用容器层次结构时才相关。如果你在一个容器中定义了一个 BeanPostProcessor,它只会在那个容器中的 bean 上工作。在一个容器中定义的 Bean 不会由另一个容器中的 BeanPostProcessor 进行后处理,即使两个容器都是同一层次结构的一部分。
回答by tn.stackoverflow
Yea I am having same issue with Spring 3. It doesn't seem to work inside Controllers. To fix the issue I created a another bean with @Service and injected that into the controller. It did work for me. Hope this would be helpful to someone as I spent all day to figure it out.
是的,我在 Spring 3 中遇到了同样的问题。它似乎在控制器中不起作用。为了解决这个问题,我用@Service 创建了另一个 bean 并将其注入控制器。它确实对我有用。希望这会对某人有所帮助,因为我花了一整天的时间来弄清楚。
回答by jediz
You can @Autowire Environmentand then environment.getProperty("name").
See https://stackoverflow.com/a/15562319/632293
你可以@Autowire Environment然后environment.getProperty("name")。见https://stackoverflow.com/a/15562319/632293
回答by AbdusSalam
You need to use PropertySourcePlaceHolder if you are using @Value annotation because it can extract the value from a properties file. If you are using java config base you need to create a bean like this
如果您使用 @Value 注释,则需要使用 PropertySourcePlaceHolder,因为它可以从属性文件中提取值。如果您使用的是 java config base,则需要像这样创建一个 bean
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
Or if you are using xml based then declare the bean accordingly.
或者,如果您使用的是基于 xml 的,则相应地声明 bean。
回答by Stefano Scarpanti
I had similar issue in my spring project, but specifically spring BATCH one. I built initially my config as below
我在 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();
}
...
}
with MyDecider shortly as below
与 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");
}
}
But in this way neither taskScheduler was wired nor pagesize was injected; both null. Thanks to Boris answer, after some try, I changed BatchConfig as below perfectly working
但是这样既没有连接 taskScheduler 也没有注入 pagesize;都为空。感谢鲍里斯的回答,经过一些尝试,我将 BatchConfig 更改为如下完美工作
...
@Bean
public Step init0(){
return stepBuilders.get("init0")
.tasklet(decider())
.build();
}
@Bean
public Tasklet decider() {
return new MyDecider();
}
...
Reason: having MyDecider construction closer to a Bean annotation in BatchConfig (the one of decider()), make spring understand that MyDecider has to be injected properly, with values found in application.property values, and wired with TaskScheduler used (because I tried also to have SpringScheduler activation, but I wanted to swith it off if jar starting option was 'send').
原因:让 MyDecider 构造更接近 BatchConfig 中的 Bean 注释(decider() 之一),让 spring 明白必须正确注入 MyDecider,在 application.property 值中找到值,并使用 TaskScheduler 连接(因为我试过也有 SpringScheduler 激活,但如果 jar 启动选项是“发送”,我想关闭它)。
NOTE: with option mode="send" spring batch job takes the way towards stepMulti and not stepMultiPolling, because MyDecider exit status was SEND and not POLLING; but that is just an explanation out of this topic, so I skip further details.
注意:使用选项 mode="send" spring 批处理作业采用 stepMulti 而不是 stepMultiPolling,因为 MyDecider 退出状态是 SEND 而不是 POLLING;但这只是本主题的一个解释,所以我跳过更多细节。
Hope this spring batch case can be helpful for someone!
希望这个春季批次案例可以对某人有所帮助!

