5.7.Application contexts 和Resource 路径
5.7. Application contexts 和Resource
路径
5.7.1. 构造application contexts
application context构造器通常使用字符串或字符串数组作为资源(比如组成context定义 的XML文件)的定位路径。
当这样的定位路径没有前缀时,指定的 Resource
类型会通过这个路径来被创建并被用来载入bean的定义,这都取决于你所指定的application context。例如,如果你使用下面的代码来创建ClassPathXmlApplicationContext
:
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
这些Bean的定义会通过classpath载入并使用ClassPathResource
。 而如果你象下面这么创建FileSystemXmlApplicationContext
:
ApplicationContext ctx = new FileSystemClassPathXmlApplicationContext("conf/appContext.xml");
这些Bean的定义会通过文件系统从相对于当前工作目录中被载入。
请注意如果定位路径使用classpath前缀或标准的URL前缀,那它就会覆盖默认的Resource
类型。因此下面的FileSystemXmlApplicationContext
...
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
...实际上会通过classpath载入其bean定义。然而它仍是个FileSystemXmlApplicationContext
。 如果后面它被当作ResourceLoader
来使用,那么任何没有使用前缀的路径依然会被当作一个文件系统路径。
5.7.1.1. 创建 ClassPathXmlApplicationContext
实例 - 简介
ClassPathXmlApplicationContext
提供了多种构造方法以便于初始化。但其核心是,如果我们仅仅提供由XML文件名组成的字符串数组(没有完整路径信息),而且还提供了Class
;那么该ClassPathXmlApplicationContext
就 会从给定的类中抽取路径信息。
希望通过一个示例把这些阐述清楚。假设有这样的目录结构:
com/ foo/ services.xml daos.xml MessengerService.class
由 'services.xml'
和 'daos.xml'
中定义的bean组成的 ClassPathXmlApplicationContext
实例会象这样地来实例化...
ApplicationContext ctx = new ClassPathXmlApplicationContext( new String[] {"services.xml", "daos.xml"}, MessengerService.class);
5.7.2. classpath*:
前缀
当构造基于XML的application context时,路径字符串可能使用特殊的 classpath*:
前缀:
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
此前缀表示所有与给定名称匹配的classpath资源都应该被获取(其中,这经常会在调用 ClassLoader.getResources(...)
) 时发生),并接着将那些资源全并成最终的application context定义。
该机制的一个用处就是做组件类型的应用组装。所有的组件都可以用通用的定位路径“发布”context定义片断, 这样当使用相同的 classpath*
前缀创建最终的application context时,所有的组件片断都会被自动装入。
请注意这个特殊的前缀是application context专用,它在构造时使用。这与 Resource
类型本身没有关联。因为同一时刻只能指向一个资源,所以不能使用 classpath*
前缀来构造实际的Resource
。
5.7.3. FileSystemResource
提示
一个并没有与 FileSystemApplicationContext
绑定的 FileSystemResource
(也就是说FileSystemApplicationContext
并不是真正的ResourceLoader
),会象你期望的那样分辨绝对和相对路径。 相对路径是相对于当前的工作目录,而绝对路径是相对与文件系统的根目录。
为了向前兼容的目的,当 FileSystemApplicationContext
是个 ResourceLoader
时它会发生变化。FileSystemApplicationContext
会简单地让所有绑定的 FileSystemResource
实例把绝对路径都当成相对路径, 而不管它们是否以反斜杠开头。也就是说,下面的含义是相同的:
ApplicationContext ctx = new FileSystemClassPathXmlApplicationContext("conf/context.xml");
ApplicationContext ctx = new FileSystemClassPathXmlApplicationContext("/conf/context.xml");
下面的也一样:(虽然把它们区分开来也很有意义,但其中的一个是相对路径而另一个则是绝对路径)。
FileSystemXmlApplicationContext ctx = ...; ctx.getResource("some/resource/path/myTemplate.txt");
FileSystemXmlApplicationContext ctx = ...; ctx.getResource("/some/resource/path/myTemplate.txt");
实际上如果的确需要使用绝对路径,那你最好就不要使用 FileSystemResource
或 FileSystemXmlApplicationContext
来确定绝对路径。我们可以通过使用 file:
URL前缀来强制使用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 it's definition via a UrlResource ApplicationContext ctx = new FileSystemXmlApplicationContext("file:/conf/context.xml");