Spring Resource之应用上下文和资源路径

1.构建应用上下文

一个应用上下文构造器一般需要一个构成Bean定义的上下为你xml字符串路径或者一个字符串数组路径作为参数。

当这样的路径没有前缀的时候,那么从哪个路径构建的资源类型,用于加载bean的定义,取决于它所处的指定的上下文环境,例如,如果你像下面一样创建一个ClassPathXMLApplicationContext :

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

Bean定义将会从classpath中加载然后做完一个ClassPathResource来使用。但还如果你像下面这样创建改一个FileSystemXxmlApplicationContext:

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

Bean定义将会从一个文件出被加载,在这个例子中将会从想对你的当前工作目录中查看。

注意在位置中中的明确的Classpath前缀或者标准的URL前缀将会覆盖缺省的创建用于加载定义的Resource类型。所以这个FileSystemXmlApplicationContext...

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

它将会从classpath中加载bean定义。但是,这仍然是一个FileSystemXmlApplicationContext。如果它经常被当成一个ResourceLoader,那么任何不带前缀的路径将会被当成是文件路径。

1.1.构建ClassPathXmlApplicationContext-快捷方式

ClassPathXmlApplicationContext提供了大量的构造函数来提供实例化的操作。设计的基本做法就是一个提供包含xml文件名称的字符串数组,而一个铜是提供了一个类:ClassPathXmlApplicationContext从提供的类中发现路径的信息。

下面的例子将吧这个表述的很清晰。看下面的文件夹布局:

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

ClassPathXmlApplicationContext实例有在servies.xml和daos.xml中定义的beans组成,可以向下面这样被实例化:

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

2.在应用上下文构造函数中资源路径的通配符

在应用上下文构造函数的值中的资源路径可能是一个只是一对一映射到目标资源的简单的路径或者是包含特殊的“classpath*:”前缀或者的ANT风格的表达式。后者都是通配符的应用。

使用这种机制的场景之一就是当来处理组件风格的应用。所有的组件能够发布上下文定义的代码片段,而且当最终的应用上下文通过使用相同的路径前缀被创建的 时候,所有的组件片段能够自动的装配在一起。

注意到这个通配符是指定用在资源路径中的 ,而且在构建的时候被解析。它和Resource类型自身没有关系。不要使用前缀classpath*:来构建构建一个真正的资源,因为一个资源只会一次指向一个资源。

2.1 ANT风格的模式

当路径含有ANT风格模式的时候:

/WEB-INF/-context.xml
 com/mycompany//applicationContext.xml
 file:C:/some/path/-context.xml
 classpath:com/mycompany//applicationContext.xml

解析器会根据这个复杂但是被定义的过程去解析通配符。它会根据上下的非通配符中获取一个Resource而且从一个URL获取。如果这个URL不是一个jar,URL或者容器指定的变体,然后一个java.io.File就会通过它获取而且通过文件系统来解析这个通配符。在一个Jar URL中,解析器会获取一个java.net.JarURLConnection或者可以手动解析这个Jar URL然后通过j意义上的可移植性
ar文件内容来解析通配符。

2.1.1意义上的可移植性

如果指定的路径已经是一个文件URL了,不管是隐式的还是现实的,因为基础的ResourceLoader是一个文件系统了,然后通配符就会保证工作在一个完全便携的风格中。
如果指定的路径是一个classpath位置,那么解析器就必须通过一个Classloader.getResource() 方法调用获取最后一个非通配符路径的URL片段。因为这个只是路径的一个,严格来说它是未定义的。在实践中,一般它是java.io.File来表示一个目录。一般在这个操作中还有移植行的考虑。

如果一个Jar URL 作为最后一个非通配符片段来获取,解析器必须能从这里面够获取一个java.net.JarURLConnection,或者手动解析这个Jar URL,一般能够读取Jar的内容并且解析通配符。这个在发布费的环境中会有效但是在一些中会出错,而且强烈建议通过通配符的方式从jar中获取资源需要在你你指定的环境中得到测试在你使用它之前。

2.2Classpath: classpath: 前缀

当构造一个基于XML的应用上下文的时候,一个特殊的classpath*:前缀:

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

这个特殊的前缀明确了所有classpath资源必须匹配给定的名字才会被获取然后组合在一起形成了最终的应用上下文的定义。
" classpath: "需要和一个PathMatcher模式联系在一起,例如 " classpath:META-INF/*-beans.xml"。在这个例子里,解决策略是想淡定简单:一个ClassLoader.getResources()调用在后面的非通配符片段中获取所有匹配的资源,然后应用相同的匹配策略对于子路径。

2.2.1关于通配符的其他说明

请注意 " classpath:"在和ANT风格的模式联系在一起的时候在模式开始之前只会在一个根目录出开始匹配,出发实际的目标文件在文件系统中。这意味着像“classpath😗.xml”不会从jar文件的根路径来检出文件而是从扩展的目录的跟路径出。这个起源于JDK中的只返回传入空的字符串的文件系统的位置的ClassLoader.getResources()方法的限制。

有找" classpath: "的ANT风格的资源都不确定一定会找到匹配的资源如果根包的搜索在多各类的路径位置处的时候,这是因为像这样的一个资源:

com/mycompany/package1/service-context.xml

可能只是一个位置,但是当一个路径像这样:

classpath:com/mycompany/**/service-context.xml

当试找去解析它的时候,这个解析器将会返回 getResource("com/
mycompany") ;第一个的URL;如果根包节点在多个classLoader位置中存在的话,实际的结束的资源可能不是在下面。因此,在这个例子中更好的使用相同的ANT风格 " classpath*: " ,它将会搜索包含根包的所有的类路径。

2.3FileSystemResource说明

没有绑定到FileSystemApplicationContext 的FileSystemResourcey也会被完全当成是你所期望的对的相对路径。相对的路径就是相对于当前的工作目录,当决定路径是相对于文件的 根目录是。

由于向后兼容的原因,当FileSystemApplicationContext是ResourceLoader的改变。FileSystemApplicationContext简单的 强迫所有的绑定的FileSystemResource实例把所有的位置路径当做相对的,不管他们是否一个开始还是不是。在实际中,这意味着下面是等价的:

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");

在实际中,如果真的绝对文件路径被需要的话,那么最好放弃使用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 its definition via a UrlResource
ApplicationContext ctx =
 new FileSystemXmlApplicationContext("file:/conf/context.xml");
posted on 2015-03-30 22:38  叼烟斗的纤夫  阅读(4081)  评论(0编辑  收藏  举报