@Value取不到值引出的spring的2种配置文件applicationContext.xml和xxx-servlet.xml
项目中经常会用到配置文件,定义成properties的形式比较常见,为了方便使用一般在spring配置文件中做如下配置:
<context:property-placeholder ignore-unresolvable="true" location="classpath*:/application.properties" />
这样在程序代码中直接用@Value("${name}")就能直接取到properties文件中定义的变量值.
但是在一个项目中发现一个情况,在Controller中取不到这个值,直接输出了${name}字符串,并没有解析出值,而在service中却能取到.有点奇怪啊,明显在Controller中貌似并没有引入properties文件中的变量,而被当做普通的字符串处理了..突然想到这个项目有2个配置文件,1个在WEB-INF下的springmvc-servlet.xml,1个在classpath下的applicationContext.xml,其中applicationContext.xml中定义有placeholder.
说实话之前并没有注意过这个配置文件的区别,一直以为只是放置的位置不一样而已,借助这次机会吧,查询到了一些资料.先看一则引入spring在web.xml中的配置:
<!-- springmvc配置开始 -->
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
<!-- springmvc配置结束 -->
<!-- Spring配置开始 -->
<listener>
<listenerclass>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/applicationContext.xml</param-value>
</context-param>
<!-- Spring配置结束 -->
可以看到分为spring配置和springmvc配置2种.其中spring配置以监听器的形式引入,不指定xml配置文件地址则默认查找WEB-INF下的applicationContext.xml文件.springmvc则以 servlet形式引入,当没有指定引入的xml配置文件地址时,则会自动引入WEB-INF下的[servlet-name]-servlet.xml文件,本例中为springmvc-servlet.xml.引入顺序为先引入spring配置,再引入servlet形式的springmvc配置.
值得注意的几点是:springmvc的配置文件中可以直接用id引入spring配置文件中定义的bean,但是反过来不可以.每一个springmvc的配置文件xxx-servlet.xml对应一个web.xml中的servlet定义.当存在多个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配置文件中的,[email protected]��查找,故只需要将placeholder重新在springmvc的配置中配置一遍,Controller中的@Value注解便能取到值了.
在xxx-servlet.xml 中,配置扫描范围时,只配置带@Controller的类,而在applicationContext.xml中可以扫描所有其他带有注解的类(也可以过滤掉带@Controller注解的类)。
//xxx-servlet.xml 中的扫描配置
<!-- 自动扫描且只扫描@Controller -->
<context:component-scan base-package="com.chrhc.**.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>
而applicationContext.xml中配置的扫描范围:
<context:component-scan base-package="com.chrhc">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>
因为在applicationContext.xml中的配置,即使不排除关于@Controller的配置,此配置文件中的关于@Controller的配置也不会起作用。
所以,把Controller、View相关的信息放到了xxx-servlet.xml中,把Model、Service之类的信息放到了applicationContext.xml中
相关推荐
在构建Java Web应用程序时,整合Struts2、Spring和Hibernate是非常常见的做法。这三个框架分别负责处理不同的层面:Struts2用于MVC(Model-View-Controller)架构中的控制层,Spring作为依赖注入和事务管理的核心,...
通过在项目的`/WEB-INF/lib`目录下添加Spring相关的jar包,并在项目中配置Spring的核心配置文件`applicationContext.xml`来启用Spring的支持。 ##### 4. 添加Hibernate 3.2支持 Hibernate是对象关系映射(ORM)...
WEB-INF下的applicationContext.xml为Spring的配置文件,struts-config.xml为Struts的配置文件,file-upload.jsp为文件上传页面,file-list.jsp为文件列表页面。 本文后面的章节将从数据持久层->业务层->Web层的...
- **@Configuration** 注解自 Spring 3.0 引入,旨在提供一种基于 Java 的配置方式来替代传统的 XML 配置文件。通过这种方式,开发者可以更加灵活地控制依赖注入和其他配置细节。 - **@Configuration** 类内部通常...
Spring配置文件一般为`applicationContext.xml`和`applicationContext-xxx.xml`,位于`src-app/config`目录下,主要用于定义Bean的注入,包括业务逻辑的具体实现类。 Hibernate配置文件的命名应与数据库表名保持...
文件存储系统,提供四种方案: - **阿里云** OSS - **腾讯云** COS - **七牛云** - 本地分布式存储 ![阿里云OSS](project-bootstrap/aliyun-oss-post-callback.png) > zheng-api 服务网关,对外暴露统一规范的...
- 数据库连接配置:在Spring的配置文件中,如applicationContext.xml,会有DataSource的配置,指定数据库连接信息。 - MyBatis的配置:mybatis-config.xml文件,包含MyBatis的全局配置和Mapper扫描路径。 - Spring ...
spring配置文件applicationContext.xml里面需要配置WeixinConfigurer,这是jwx唯一必须配置项,如果没有配置,启动阶段会报错。 <context:component-scan base-package="com.github.jweixin.jwx.weixin.service" />...
- 需要在Spring配置文件(如`applicationContext.xml`或`dispatcher-servlet.xml`)中配置`ViewResolver`,例如使用`InternalResourceViewResolver`,设置前缀和后缀以便找到JSP页面。 ```xml <bean class="org....
然后,在 Spring 配置文件中,我们需要添加以下配置,以便 Spring 可以自动扫描到该类: ```xml <context:annotation-config/> <context:component-scan base-package="com.xxx.servlet"> </context:component-scan...