第一个,为spring的service和dao进行配置的配置文件,对应springMVC的父context applicationContext
<!--applicationContext.xml --> <context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties" />
第二个,为spring MVC的controller进行配置的配置文件,对应springMVC里的子context webapplicationContext,该webapplicationContext继承自父context,所以可以访问父context的bean。
<!--spring-mvc.xml --> <!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="com.xxxx.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>
service 里可以直接值使用@Value("${someprop}")的方式直接拿到属性值,
对于controller来说,就没有那么简单了,不能直接使用@Value("${someprop}")注入属性值,参阅外国达人的分析
Spring @Value annotation in @Controller class not evaluating to value inside properties file
引用
It seems that the question has been already asked Spring 3.0.5 doesn't evaluate @Value annotation from properties
The difference between web app root and servlet application contexts is one of the top sources of confusion in Spring, see difference between applicationContext and spring-servlet.xml in spring
From @Value javadoc :
Note that actual processing of the @Value annotation is performed by a BeanPostProcessor
From Spring documentation:
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.
就是说@Value是通过BeanPostProcessor来处理的,而webapplicationContex和applicationContext是单独处理的,不是继承的,所以webapplicationContex不能使用父容器的属性值。
要作的就是单独给webapplicationContex设置property-placeholder
<!--spring-mvc.xml --> <!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="com.xxxx.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan> <!-- 单独为webapplicationContext注入placeholder --> <context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties" />
这样就可以使用@Value为Controller注入属性了,还有个小前提,就是这个 属性值不能是static的,static的@Value就没有效果了。