@Controller类中的Spring @Value批注不计算属性文件中的值

我是Spring的新手,并尝试使用@Value("${loginpage.message}")批注在带有@Controller批注的批注中注入一个带有值的string,并且我的string的值被评估为string"${loginpage.message}"而不是在我的属性文件里面。

下面是我想要注入的string“消息”的控制器。

 @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}")属性文件中的值,我都会收到一个exception。

看来这个问题已经被问到Spring 3.0.5没有从属性中评估@Value注解

Web应用程序根和servlet应用程序上下文之间的差异是Spring中混淆的头号之一,请参阅Spring Framework中的applicationContext.xml和spring-servlet.xml之间的区别。

来自@Value javadoc:

请注意,@Value注释的实际处理由BeanPostProcessor执行

从Spring文档:

BeanPostProcessor接口的范围是每个容器。 这只与使用容器层次结构有关。 如果你在一个容器中定义了一个BeanPostProcessor,它只会在那个容器中的bean上工作。 在一个容器中定义的Bean不会由另一个容器中的BeanPostProcessor进行后处理,即使两个容器都是同一层次结构的一部分。

是的,我与Spring 3有相同的问题。它似乎并没有在控制器内部工作。 为了解决这个问题,我使用@Service创build了另一个bean,并将其注入到控制器中。 它确实为我工作。 希望这对我整天花时间了解的人有所帮助。

你可以@Autowire Environment ,然后environment.getProperty("name") 。 请参阅https://stackoverflow.com/a/15562319/632293

如果使用@Value注释,则需要使用PropertySourcePlaceHolder,因为它可以从属性文件中提取值。 如果你正在使用java config base,你需要像这样创build一个bean

 @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } 

或者如果你使用的是基于xml的话,相应地声明这个bean。

我在我的春季项目中有类似的问题,但特别是春季BATCH之一。 我最初build立我的configuration如下

 @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连线,也没有pagesize被注入; 两者都为空。 感谢鲍里斯的回答,经过一番尝试,我改变了BatchConfig如下完美的工作

 ... @Bean public Step init0(){ return stepBuilders.get("init0") .tasklet(decider()) .build(); } @Bean public Tasklet decider() { return new MyDecider(); } ... 

原因:让MyDecider构造更接近BatchConfig( decider()之一 )中的Bean注解,让Spring知道必须正确注入MyDecider,在application.property值中find值,并使用TaskScheduler连接(因为我试过也有SpringScheduler激活,但如果jar启动选项是'发送'),我想把它closures。

注意:在选项mode =“send”的情况下,Spring批处理作业采用stepMulti而不是stepMultiPolling,因为MyDecider退出状态是SEND而不是POLLING; 但是这只是对这个话题的一个解释,所以我略过了一些细节。

希望今年spring的批处理案例能对别人有所帮助!