我是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}")
之类的属性文件中的值时,我都会遇到异常。
答案 0 :(得分:65)
似乎问题已经被问到Spring 3.0.5 doesn't evaluate @Value annotation from properties
Web应用程序根目录和servlet应用程序上下文之间的区别是Spring中混淆的主要原因之一,请参阅Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
来自@Value
javadoc:
注意@Value注释的实际处理由a执行 的BeanPostProcessor
BeanPostProcessor接口的范围是每个容器。这仅在您使用容器层次结构时才有意义。如果在一个容器中定义BeanPostProcessor,它将只对该容器中的bean执行操作。在一个容器中定义的Bean不会被另一个容器中的BeanPostProcessor进行后处理,即使两个容器都属于同一层次结构。
答案 1 :(得分:7)
是的,我遇到了与Spring 3相同的问题。它似乎不适用于Controllers。 为了解决这个问题,我用@Service创建了另一个bean并将其注入控制器。 它对我有用。希望这会对某人有所帮助,因为我花了一整天时间来弄明白。
答案 2 :(得分:3)
您可以@Autowire Environment
然后environment.getProperty("name")
。
见https://stackoverflow.com/a/15562319/632293
答案 3 :(得分:1)
如果使用@Value注释,则需要使用PropertySourcePlaceHolder,因为它可以从属性文件中提取值。如果您使用的是java配置库,则需要创建一个像这样的bean
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
或者,如果您使用的是基于xml,则相应地声明bean。
答案 4 :(得分:0)
我的春季项目有类似的问题,但特别是春季BATCH。我最初建立了如下配置
@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既没有连线,也没有注入页面大小;都是空的。感谢Boris回答,经过一番尝试后,我将BatchConfig更改为完全正常工作
...
@Bean
public Step init0(){
return stepBuilders.get("init0")
.tasklet(decider())
.build();
}
@Bean
public Tasklet decider() {
return new MyDecider();
}
...
原因:让MyDecider构造更接近BatchConfig中的Bean注释( decider()之一),让Spring知道必须正确注入MyDecider,并在application.property值中找到值,并使用了TaskScheduler(因为我也尝试过激活SpringScheduler,但是如果jar启动选项是'send',我想把它关掉)。
注意:使用选项模式=“发送”弹出批处理作业采用stepMulti而不是stepMultiPolling,因为MyDecider退出状态是SEND而不是POLLING;但这只是本主题的解释,所以我跳过了进一步的细节。
希望这个春季批案可以对某人有所帮助!