ITEEDU

Spring加载配制文件详解

主要涉及的类:

  1. XMLBeanFactory
  2. ClassPathXMLApplicationContext
  3. FileSystemXMLApplicationContext
  4. XMLWebApplicationContext

ApplicationContext的基本功能与BeanFactory很相似,它也负责读取Bean定义档,维护Bean之间的关系等,然而ApplicationContext提供的一个应用程序所需的更完整的框架功能:

  1. ApplicationContext提供取得资源文件更方便的方法。
  2. ApplicationContext提供文字讯息解析的方法,并支持国际化(Internationalization, I18N)讯息。
  3. ApplicationContext可以发布事件,对事件感兴趣的Bean可以接收到这些事件。

建议使用ApplicationContext来取代BeanFactory

XMLBeanFactory 引用资源

Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory1 = new XmlBeanFactory(resource);

利用FileSystemResource,则配置文件必须放在project直接目录下,或者写明绝对路径,否则就会抛出找不到文件的异常。

ClassPathResource resource2 = new ClassPathResource("beans.xml");
BeanFactory factory2 = new XmlBeanFactory(resource2);

ClassPathXMLApplicationContext  编译路径

一次可以加载多个配制文件。

传入参数的路径是相对于classpath的配置的。可以将applicationContext.xml放到classpath下,对于web项目就是WEB-INF/classes这个目录,或者WEB-INF/lib下。

Src默认是在classpath的配置中的,所以可以直接放到src路径。

// src目录下
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});

// src/conf 目录下的
ApplicationContext ac=new ClassPathXMLApplicationContext("conf/appcontext.XML");

//加file:前缀可以加载绝对路径
ApplicationContext ac=new ClassPathXMLApplicationContext("file:G:/Test/src/appcontext.XML");

 

FileSystemXMLApplicationContext文件系统的路径

一次可以加载多个配制文件。

可以指定XML定义文件的相对路径或者绝对路径来读取定义文件。

ApplicationContext ac=new FileSystemXMLApplicationContext("G:/Test/src/appcontext.XML");

方法一:

// src目录下
ApplicationContext ac = new FileSystemXmlApplicationContext (new String[] {"applicationContext.xml", " applicationContext_task.xml "});

String[] path={" applicationContext.xml"," applicationContext_task.xml"};
ApplicationContext context = new FileSystemXmlApplicationContext(path);

方法二:

//用通配符加载一批配制文件
String path=" spring/applicationContext*.xml";
ApplicationContext context = new FileSystemXmlApplicationContext(path);

方法三:

ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:地址");

没有classpath的话就是从当前的工作目录

XMLWebApplicationContext

XmlWebApplicationContext ctx = new XmlWebApplicationContext();
ctx.setConfigLocations(new String[] {"/WEB-INF/ applicationContext.xml");
ctx.setServletContext(pageContext.getServletContext());
ctx.refresh();

 

文件路径总结

前缀

“classpath:”在classpath的配置中搜索,不管用什么对象加载。

“file:” 在文件系统中搜索,不管用什么对象加载。

“classpath*:” 所有与给定名称匹配的classpath资源都应该被获取。

通配符可移植性

如果给定的路径已经是一个文件URL(可以是显式的或者是隐式的),由于基本的ResourceLoader是针对文件系统的,那么通配符一定能够移植。

如果给定的路径是一个classpath的位置,那么解析器必须通过一个 Classloader.getResource() 调用获得最后一个非通配符路径片断的URL。因为这仅仅是一个路径的节点(不是最终的文件), 所以它并未确切定义(在 ClassLoader Javadocs里) 此处究竟会返回什么类型的URL。一般情况下,当classpath资源解析为一个文件系统位置时, 返回一个代表目录的 java.io.File;当解析为jar位置时, 返回某类jar URL。当然,这个操作涉及到可移植性。

如果从最后一个非通配符片断中获得一个jar URL,那么解析器一定能从中取得一个 java.net.JarURLConnection,或者手动解析jar URL以遍历jar文件,从而解析通配符。这一操作在大多数环境中能正常工作,不过也有例外,因此我们强烈建议特定环境中的jar资源通配符解析应在正式使用前要经过彻底测试。

Classpath*: 的可移植性

当构造基于XML的application context时,路径字符串可能使用特殊的 classpath*: 前缀:

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

此前缀表示所有与给定名称匹配的classpath资源都应该被获取(其中,这经常会在调用 ClassLoader.getResources(…)) 时发生),并接着将那些资源全并成最终的application context定义。

带通配符的classpath依赖于底层classloader的 getResources() 方法。现在大多数的应用服务器提供自己的classloader实现,它们在处理jar文件时的行为也许会有所不同。 要测试 classpath*: 是否有效,可以简单地用classloader从classpath中的jar文件里加载一个文件: getClass().getClassLoader().getResources(“<someFileInsideTheJar>”)。针对两个不同位置但有相同名字的文件来运行测试。如果结果不对,那么就查看一下应用服务器的文档,特别是那些可能影响classloader行为的设置。

FileSystemResource 说明

一个并没有与 FileSystemApplicationContext 绑定的 FileSystemResource(也就是说FileSystemApplicationContext 并不是真正的ResourceLoader),会象你期望的那样分辨绝对和相对路径。相对路径是相对于当前的工作目录,而绝对路径是相对与文件系统的根目录。

为了向前兼容的目的,当 FileSystemApplicationContext 是个 ResourceLoader 时它会发生变化。FileSystemApplicationContext 会简单地让所有绑定的 FileSystemResource 实例把绝对路径都当成相对路径,而不管它们是否以反斜杠开头。也就是说,下面的含义是相同的:

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

实际上如果的确需要使用绝对路径,那你最好就不要使用 FileSystemResource 或 FileSystemXmlApplicationContext来确定绝对路径。我们可以通过使用 file: URL前缀来强制使用UrlResource