spring 资源访问 Resource

  在jdk的api中,资源访问基本上都是通过URL类和IO来完成的,首先我们来介绍一下jdk中的资源访问

  在j2se中,我们一般通过ClassLoader的getResource()方法来定位查找资源:

	public static void main(String[] args) throws IOException, URISyntaxException {
		URL url = Thread.currentThread().getContextClassLoader().getResource("format.properties");
		Properties p = new Properties();
		p.load(url.openStream());
		System.out.println(p.get("chengan"));
		System.out.println(url.getProtocol());
	}

   ClassLoader的getResource()方法访问资源有一个限制,资源的位置只能在classpath路径下或者classpath的子路径下,如果format.properties文件的路径不在classpath路径下,getResource()方法是找不到文件的,比如我们再开发web项目的时候,jdbc.properties一般都会放到WEB-INF下新建一个文件保存,此时在使用ClassLoader获取,就获取不到,下面我们就需要使用servletContext提供的方法,getResource()方法参数可以使用"/"作为路径,比如format.properties位于classpath路径下的test包下(getResource()方法参数的起始路径为classpath):

URL url = Thread.currentThread().getContextClassLoader().getResource("test/format.properties");

  

  在j2ee中,可以使用ServletContext提供的方法getResource()来访问资源:

		response.setContentType("text/html");
		URL url = request.getSession().getServletContext().getResource("/WEB-INF/config/jdbc.properties");
		response.getWriter().print(url);

  jdbc.properties文件放在WEB-INF的config文件下,servletContext的getResource方法以WebRoot为起始路径,上面代码运行的结果为:

  jndi:/localhost/SpringDemo/WEB-INF/config/jdbc.properties

spring的资源访问提供了统一的接口:Resource

spring在设计上使用了策略模式,针对不同的资源访问,提供了不同的实现类,常用的实现类有:

UrlResource:对java.net.URL访问的封装

ServletContextResource:对servletContext访问资源的封装

FileSystemResource:访问文件系统资源的封装

InputStreamResource:流操作资源访问

ContextResource:该接口是对访问容器资源的接口,提供一系列实现该接口的类

在spring中,访问资源的入口在applicationContext中,applicationContext继承了ResourcePatternResolver接口

public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

	Resource[] getResources(String locationPattern) throws IOException;

}

 ResourcePatternResolver又继承了ResourceLoader接口:

public interface ResourceLoader {

	/** Pseudo URL prefix for loading from the class path: "classpath:" */
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;


	Resource getResource(String location);

	ClassLoader getClassLoader();

}

在访问资源时,可以指定访问资源的方式:

	public Resource getResource(String location) {
		Assert.notNull(location, "Location must not be null");
                //常量CLASSPATH_URL_PREFIX值为:classpath:
		if (location.startsWith(CLASSPATH_URL_PREFIX)) {
			return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
		}
		else {
			try {
				// Try to parse the location as a URL...
				URL url = new URL(location);
				return new UrlResource(url);
			}
			catch (MalformedURLException ex) {
				// No URL -> resolve as resource path.
				return getResourceByPath(location);
			}
		}
	}

 上面是ResourceLoader的方法getResource()的默认实现,由上述代码可知,在指定资源的位置时,如果前缀指定为“classpath:",那么会使用ClassPathResource,否则默认使用UrlResource,如果出错会使用ClassPathResource

猜你喜欢

转载自abc08010051.iteye.com/blog/1973831