【深入理解】@Value取不到值,直接输出了${name}字符串

项目中经常会用到配置文件,定义成properties的形式比较常见,为了方便使用一般在spring配置文件中做如下配置:

这样在程序代码中直接用@Value(“ name)propertiesController {name}字符串,并没有解析出值,而在service中却能取到。明显在Controller中并没有引入properties文件中的变量,而被当做普通的字符串处理了。
经过排查这个项目的web.xml中有2个配置文件,1个spring-config.xml,1个spring-mvc.xml,其中spring-config.xml中定义有placeholder。
在web.xml中的配置片段如下:

<!-- Spring配置文件开始 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:spring-config.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring配置文件结束 -->

<!-- springmvc配置开始 -->
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<!-- springmvc配置结束 -->

可以看到分为spring配置和springmvc配置2种。
其中spring配置以监听器的形式引入,不指定xml配置文件地址则默认查找WEB-INF下的applicationContext.xml文件。
springmvc则以servlet形式引入,当没有指定引入的xml配置文件地址时,则会自动引入WEB-INF下的[servlet-name]-servlet.xml文件。本例中为spring-mvc.xml,引入顺序为先引入spring配置,再引入servlet形式的springmvc配置。

值得注意的几点是:
1、springmvc的配置文件中可以直接用id引入spring配置文件中定义的bean,但是反过来不可以。
2、每一个springmvc的配置文件xxx-servlet.xml对应一个web.xml中的servlet定义。
3、当存在多个springmvc配置文件时候,他们之间是不能互相访问的。

在百度中别人的帖子中看到一段应该是官方的原文解释,我摘抄过来并粗糙的直译一下:
Spring lets you define multiple contexts in a parent-child hierarchy.
spring允许你定义多个上下文在父子继承关系中。
The applicationContext.xml defines the beans for the “root webapp context”, i.e. the context associated with the webapp.
applicationContext.xml文件是为了”根webapp应用上下文”定义bean,也就是说它的上下文是和webapp想关联的。
The spring-servlet.xml (or whatever else you call it) defines the beans for one servlet’s app context. There can be many of these in a webapp,
spring-servlet.xml文件(或是其他的你习惯的称呼)是为了一个servlet应用上下文呢定义bean。在一个webapp中可以有多个此配置文件。
one per Spring servlet (e.g. spring1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2).
每一个spring的servlelt(例如: 名为spring1的servlet拥有配置文件spring1-servlet.xml, 名为spring2的servlet拥有配置文件spring2-servlet.xml)。
Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.
在spring-servlet.xml中定义的bean可以直接引用在applicationContext.xml中定义的bean,但是反过来不可以。
All Spring MVC controllers must go in the spring-servlet.xml context.
所有springmvc的Controller必须在spring-servlet.xml对应的上下文中运行。
In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets
在大多数简单的情况下, applicationContext.xml对应的上下文并不必须。它通常用来包含那些bean用来在webapp中所有servlet之间共享。
in a webapp. If you only have one servlet, then there’s not really much point, unless you have a specific use for it.
如果你只有一个servlet, 那么实际没有什么必要定义applicationContext.xml, 除非你有特别应用。

解决:
回到最开始的@Value取不到值的问题,现在可以清楚是由于Controller是定义在springmvc的servlet配置文件中的,故只需要将placeholder重新在springmvc的配置中配置一遍,Controller中的@Value注解便能取到值了。

转自:http://blog.csdn.net/zuoyixiao/article/details/54288329


看完这篇文章最大的收益是清楚了web.xml里面配置在spring中的意义,一个是定义监听器application作为全局控制,一个是springmvc的servlet局部控制(在有多个servlet的情况下)

按文章意思理解servlet可以调用application的bean,但是application不能调用servlet的bean,那么原先我的bean就是放在application里的,为什么servlet没有拿到呢?似乎有点自相矛盾!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值