起因
标准JDK中使用 java.net.URL 来处理资源,但有很多不足,例如不能限定classpath,不能限定 ServletContext 路径。
所以,Spring提供了 Resource 接口。
注意,Spring提供的Resource抽象不是要取代(replace)标准JDK中的功能,而是尽可能的封装(wrap)它。
例如,UrlResource 就封装了一个URL。
介绍
Spring内置了很多Resource实现,以用于不同情况。如下:
UrlResource
,ClassPathResource
,FileSystemResource
,ServletContextResource
,InputStreamResource
,ByteArrayResource
;
基本上可以根据名字判断出各自的适用环境。
使用
ResourceLoader,这个接口只有一个方法,用于返回Resource实例。
ApplicationContext接口继承了该接口,就是说,所有的ApplicationContext实现都实现了其方法,能够返回一个Resource实例。
默认情况下,根据不同的ApplicationContext实现,会返回不同的Resource类型,例如:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
1 如果ctx是一个ClassPathXmlApplicationContext,那会返回一个ClassPathResource。
2 如果ctx是一个FileSystemXmlApplicationContext ,那会返回一个FileSystemResource。
3 如果ctx是一个WebApplicationContext,那会返回一个ServletContextResource。
但是,可以通过前缀来指定返回的Resource
实例类型:
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
前缀列表:
Prefix | Example | Explanation |
classpath: | classpath:config/app.xml | 从classpath中加载。 |
file: | file:///data/app.xml | FileSystem的URL。 |
http: | http://myserver/logo.png | URL。 |
(none) | /data/app.xml | 依赖具体的ApplicationContext实现。 |
另外,ClassPathXmlApplicationContext 可以根据 Class的路径 推断出资源路径。需要在同一个包下。
new ClassPathXmlApplicationContext(new String[]{"a.xml","b.xml"}, Config.class);
上面这个例子,要求a.xml、b.xml、Config.class在同一个包下。
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx = new FileSystemXmlApplicationContext("/conf/context.xml");
另外,上面这两个又分别等效于下面这两个:
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("some/resource/path/myTemplate.txt");
FileSystemXmlApplicationContext ctx = ...;
ctx.getResource("/some/resource/path/myTemplate.txt");
2、由其他ApplicationContext实例返回。这种情况下,FileSystemResource会按我们预期的来处理相对路径和绝对路径:相对路径是相对于当前工作路径;绝对路径是FileSystem的根路径。
FileSystemResource
/FileSystemXmlApplicationContext
,使用URL前缀file:来返回UrlResource即可。如下:// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
ApplicationContext ctx = new FileSystemXmlApplicationContext("file:///conf/context.xml");
ps:
做了一个小demo放在码云,有兴趣的可以down下来看看。