在web项目里使用了spring框架,我们经常需要在web容器启动时自动初始化spring容器。要想实现这一功能,就需要在web.xml中增加一个上下文参数,指定spring的配置文件applicationContext.xml。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/config/applicationContext.xml</param-value>
</context-param>
参数名称contextConfigLocation是固定属性名,不可写错。为什么呢,
/WEB-INF/classes/config/applicationContext.xml说明applicationContext.xml是在源代码下的config目录下的。
光声明配置文件的路径是不够的,还要声明spring框架的web上下文加载监听器。配置Listener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
监听器设置好后,启动web容器时,就会启动ContextLoaderListener的方法contextInitialized() 。而在方法contextInitialized() 中有以下代码:
- public void contextInitialized(ServletContextEvent event) {
- this.contextLoader = createContextLoader();
- if (this.contextLoader == null) {
- this.contextLoader = this;
- }
- this.contextLoader.initWebApplicationContext(event.getServletContext());
- }
借助容器的上下文this.contextLoader去初始一个spring的应用上下文initWebApplicationContext,使用到了ContextLoader这个类
在ContextLoader类中初始化时有这样一块static代码
-
static {
// Load default strategy implementations from properties file.
- // This is currently strictly internal and not meant to be customized
- // by application developers.
- try {
- //这一句会去加载同在此包下的一个properties文件的值(ContextLoader.properties)
- ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
- defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
- }
- catch (IOException ex) {
- throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
- }
- }
ContextLoader.properties的属性文件中有org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
可以通过属性文件反射生成XmlWebApplicationContext,而在XmlWebApplicationContext中有这个常量
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
说明spring的web默认加载spring文件的启动位置了,是在web-inf下,如果想指定新的目录,可以在web的上下文参数中指定路径,那么在哪个参数中指定呢。
接下来我们继续看ContexLoader类,里面有一个常量。
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
而XmlWebApplicationContext对象正是调用了这个参数去设置启动位置
- wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
再往上看XmlWebApplicationContext继承的AbstractRefreshableConfigApplicationContext类中的setConfigLocation方法将此抽象类中的String[] configLocations值填充
并在AbstractRefreshableConfigApplicationContext类中我们看到spring对默认启动文件位置和配置启动文件位置的支持
- protected String[] getConfigLocations() {
- return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
-
protected String[] getConfigLocations() {
-
return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
}
1. 首先 classpath是指 WEB-INF文件夹下的classes目录
2. classpath 和 classpath* 区别:
classpath:只会到你的class路径中查找找文件;
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.
如果applicationContext.xml配置文件存放在WEB-INF下面
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext*.xml</param-value>
</context-param>
如果applicationContext.xml配置文件存放在src目录下
context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
需要注意的是,部署到应用服务器后,src目录下的配置文件会和class文件一样,自动copy到应用的 classes目录下,spring的 配置文件在启动时,加载的是web-info目录下的applicationContext.xml, 运行时使用的是web-info/classes目录下的applicationContext.xml。因此,不管applicationContext.xml配置文件存放在src目录下,还是存放在WEB-INF下面,都可以用下面这种方式来配置路径:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext*.xml</param-value>
</context-param>
当有多个配置文件加载时,可采用下面代码来配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:conf/spring/applicationContext_core*.xml,
classpath*:conf/spring/applicationContext_dict*.xml,
classpath*:conf/spring/applicationContext_hibernate.xml,
......
</param-value>
</context-param>
也可以用下面的这种方式:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:**/applicationContext-*.xml</param-value>
</context-param>
"**/"表示的是任意目录;
"**/applicationContext-*.xml"表示任意目录下的以"applicationContext-"开头的XML文件。
Spring配置文件最好以"applicationContext-"开头,且最好把所有Spring配置文件都放在一个统一的目录下,也可以分模块创建。