@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的批处理案例能对别人有所帮助!