雷聪

个人站点

欢迎来到我的个人站点~
一面技术,一面生活!


spring加载配置文件的方式

前言

本篇博客主要简单说明 spring 加载资源路径的几种方式。以及 classpathclasspath* 的区别。

前提知识

首先 classpath是指 WEB-INF文件夹下的classes目录

解释classes含义:

  1. 存放各种资源配置文件,比如:log4j.properties,springmvc.xml
  2. 存放模板文件,比如:commons.tld
  3. 存放class文件对应的是项目开发时的src目录编译文件

总结:这是一个定位资源的入口

本篇主要介绍:

  1. spring 加载配置文件的几种方式
  2. classpathclasspath* 加载资源文件的区别

一、 使用构造方法加载spring配置文件

基本加载方式

使用构造器加载资源配置文件来获取 spring 容器,通常将字符串或字符串数组作为资源的位置路径。当这样的位置路径没有前缀(如没有加 classpath),如按照以下方式创建ClassPathXmlApplicationContext

ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");

由于使用了 ClassPathResource 加载,所以 spring 加载配置文件的时候,会从类路径开始加载,这种方式也是我们使用构造方法初始化 spring 容器时最常用的一种方式

但如果使用 FileSystemXmlApplicationContext 来加载 spring 配置的话:

ApplicationContext ctx =
    new FileSystemXmlApplicationContext("conf/appContext.xml");

会从当前操作系统的文件系统根目录开始加载,比如 c:/conf/appContext.xml;

还有一种方式,如果使用 FileSystemXmlApplicationContext 来加载 spring 配置的话,加上classpath 前缀就会从类路径开始加载:

ApplicationContext ctx =
    new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");

这样就会从项目的类路径开始查找 conf/appContext.xml 配置文件了,但是值得注意的是:这种使用 Filesystem 加载的方式,本质上来说还是从系统的根目录开始查找的,但是使用了 classpath 前缀来告诉 spring 从项目的类路径开始查找。

ClassPathXmlApplicationContext提供的其他方式

ClassPathXmlApplicationContext 这个类提供了一系列的构造方法来方便实例化,基本的想法是只要能够快速的定位到这个文件就可以加载,这个类的大纲结构如下图所示:

1528159875065

这里举个例子,假设文件的目录结构如下:

com/
  foo/
    services.xml
    daos.xml
    MessengerService.class

如果想要加载 services.xmldaos.xml 这两个配置文件的话,可以使用以下的方式:

ApplicationContext ctx = new ClassPathXmlApplicationContext(
    new String[] {"services.xml", "daos.xml"}, MessengerService.class);

二、web.xml 中加载spring容器的配置文件

在使用 Java 开发 web项目时,需要在 web.xml 中指定 spring 配置文件的位置:

  <!-- 全局配置参数 加载spring 配置 -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>
  
  <!-- spring监听器 -->
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener> 

因为通常配置文件有多个,所以一般会使用通配符的方式。可以使用 Ant-style 通配符来匹配,* 表示匹配 0 或任意数量的字符。加载可以分为两种方式:classpathclasspath*

Ant 路径通配符

Ant 路径通配符支持 ?*** 。这里需要注意的是,通配符匹配不会包括目录分隔符/

  • ?匹配一个字符,如 config?.xml,将匹配 config2.xml
  • *匹配 0 个或多个字符,如 applicationContext-*.xml 可以匹配 applicationContext-dao.xmlapplicationContext-service.xml
  • **匹配路径中的 0 个或多个目录 ,如 cn/**/config.xml 将匹配 cn/javax/spring/config.xml ,也匹配 cn/config.xml

classpathclasspath* 的区别

  1. classpath 不包含通配符:用于加载类路径(包括 jar 包)中的一个且仅一个资源;对于多个匹配的也只返回一个。
  2. classpath 包含通配符: 用于加载类路径下的资源,但是不包括 jar 包;对于同名的重复的资源只返回一个。
  3. classpath* 不论是否包含通配符:都加载类路径(包括 jar 包)中的多个同名资源。

测试:

由于 spring-beans 包下有 META-INF 目录,目录下面有一些 license.txt 、notice.txt 资源,这里使用对比的方式分别测试如果在 项目resource 目录下包含有有同名文件和没有同名文件的情况。

测试代码如下:

package xyz.allenlei.test;

import java.io.IOException;

import org.junit.Test;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;


/**
 * 测试classpath 和 classpath* 的区别
 * @author 雷聪
 *	
 */
public class SpringResourceTest {
	
	/**
	 * classpath 加载资源的测试
	 * @throws IOException
	 */
	@Test
	public void testClasspath() throws IOException {
		// 创建路径匹配对象
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 
		// 加载资源文件
		Resource[] resources = resolver.getResources("classpath:META-INF/notice.txt");
		// 查看加载了几个资源文件
		System.out.println(resources.length);
		
		// 使用通配符方式加载
		resources = resolver.getResources("classpath*:META-INF/*.txt");
		// 查看加载了几个资源
		System.out.println(resources.length);
	}
}

有个小细节说明一下:

使用类路径加载资源文件 的时候第一个字符写不写/是没有区别的,因为不管加不加解析的时候都是一样的,加上的话,解析的时候会自动去掉。下面是 spring 源码中解析路径中的一段:

protected Resource[] findAllClassPathResources(String location) throws IOException {
	String path = location;
	if (path.startsWith("/")) {
		path = path.substring(1);
	}

也就是说:

<param-value>classpath:spring/applicationContext-*.xml</param-value>
<param-value>classpath:/spring/applicationContext-*.xml</param-value>

对项目来说是没有区别的。


参考: https://spring.io/docs/reference


转载请注明: 雷聪的博客 » spring加载配置文件的方式

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦