classpath: spring 中的查找方式
Spring可以通过指定classpath*:与classpath:前缀加路径的方式从classpath加载文件,如bean的定义文件.classpath*:的出现是为了从多个jar文件中加载相同的文件.classpath:只能加载找到的第一个文件.
比如 resource1.jar中的package 'com.test.rs' 有一个 'jarAppcontext.xml' 文件,内容如下:
<bean name="ProcessorImplA" class="com.test.spring.di.ProcessorImplA" />
resource2.jar中的package 'com.test.rs' 也有一个 'jarAppcontext.xml' 文件,内容如下:
<bean id="ProcessorImplB" class="com.test.spring.di.ProcessorImplB" />
通过使用下面的代码则可以将两个jar包中的文件都加载进来
ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath*:com/test/rs/jarAppcontext.xml");
而如果写成下面的代码,就只能找到其中的一个xml文件(顺序取决于jar包的加载顺序)
ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/test/rs/jarAppcontext.xml");
classpath*:的使用是为了多个component(最终发布成不同的jar包)并行开发,各自的bean定义文件按照一定的规则:package+filename,而使用这些component的调用者可以把这些文件都加载进来.
classpath*:的加载使用了classloader的 getResources()
方法,如果是在不同的J2EE服务器上运行,由于应用服务器提供自己的classloader实现,它们在处理jar文件时的行为也许会有所不同。 要测试classpath*:
是否有效,可以用classloader从classpath中的jar文件里加载文件来进行测试:getClass().getClassLoader().getResources("<someFileInsideTheJar>")
。(上面的例子是在sun的jre中运行的状态)
从Spring的源码,在PathMatchingResourcePatternResolver类中,我们可以更清楚的了解其对的处理:如果是以classpath*开头,它会遍历classpath.
- protected Resource[] findAllClassPathResources(String location) throws IOException {
- String path = location;
- if (path.startsWith("/")) {
- path = path.substring(1);
- }
- Enumeration resourceUrls = getClassLoader().getResources(path);
- Set<Resource> result = new LinkedHashSet<Resource>(16);
- while (resourceUrls.hasMoreElements()) {
- URL url = (URL) resourceUrls.nextElement();
- result.add(convertClassLoaderURL(url));
- }
- return result.toArray(new Resource[result.size()]);
- }
http://blog.csdn.net/kkdelta/article/details/5560210,简介了在JAVA里遍历classpath中读取找到的所有符合名称的文件.
另外在加载resource的时候,其他前缀的意义如下表所示:注意classpath*只能用与指定配置文件的路径,不能用在用于
getResource的参数.如
appContext.getResource("classpath*:conf/bfactoryCtx.xml")会异常的.
前缀 | 例子 | 说明 |
---|---|---|
classpath: |
|
从classpath中加载。 |
file: |
|
作为 |
http: |
|
作为 |
(none) |
|
根据 |
|
从Spring的源码可以看出原因:如果是classpath:开头,从classpath加载,否则尝试URL,如果失败,调用 getResourceByPath
- public Resource getResource(String location) {
- Assert.notNull(location, "Location must not be null");
- 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);
- }
- }
- }
getResourceByPath会被不同ApplicationContext
实现覆盖.
如 GenericWebApplicationContext覆盖为如下:
- protected Resource getResourceByPath(String path) {
- return new ServletContextResource(this.servletContext, path);
- }
- 如 FileSystemXmlApplicationContext覆盖为如下:
- protected Resource getResourceByPath(String path) {
- if (path != null && path.startsWith("/")) {
- path = path.substring(1);
- }
- return new FileSystemResource(path);
- }
最终从文件加载的时候仍然是JAVA中常见的读取文件的方法:
如ClassPathResource得到inputstream的方法是利用class loader.
- public InputStream getInputStream() throws IOException {
- InputStream is;
- if (this.clazz != null) {
- is = this.clazz.getResourceAsStream(this.path);
- }
如FileSystemResource得到inputstream的方法是利用FileInputStream.
public InputStream getInputStream() throws IOException {
return new FileInputStream(this.file);
}
如ServletContextResource得到inputstream的方法是利用servletContext.getResourceAsStream.
- public InputStream getInputStream() throws IOException {
- InputStream is = this.servletContext.getResourceAsStream(this.path);
- if (is == null) {
- throw new FileNotFoundException("Could not open " + getDescription());
- }
- return is;
- }
classpath: spring 中的查找方式的更多相关文章
- Spring中基于注解方式管理bean
操作步骤 第一步:导入相关jar包 spring IoC的基本包 Spring支持注解的Jar包 第二步:创建Spring配置文件,ApplicationContext.xml 引入约束和开启注解扫描 ...
- Spring中的注入方式 和使用的注解 详解
注解:http://www.cnblogs.com/liangxiaofeng/p/6390868.html 注入方式:http://www.cnblogs.com/java-class/p/4727 ...
- Java Spring 中你不知道的注入方式
前言 在Spring配置文件中使用XML文件进行配置,实际上是让Spring执行了相应的代码,例如: 使用<bean>元素,实际上是让Spring执行无参或有参构造器 使用<prop ...
- Spring中的注入方式
在Spring配置文件中使用XML文件进行配置,实际上是让Spring执行了相应的代码,例如: 使用<bean>元素,实际上是让Spring执行无参或有参构造器 使用<propert ...
- 170330、Spring中你不知道的注入方式
前言 在Spring配置文件中使用XML文件进行配置,实际上是让Spring执行了相应的代码,例如: 使用<bean>元素,实际上是让Spring执行无参或有参构造器 使用<prop ...
- spring中xml配置方式和注解annoation方式(包括@autowired和@resource)的区别
xml文件中配置itemSqlParameterSourceProvider是可以的: <bean id="billDbWriter" class="com.aa. ...
- 事务理解及Spring中的事务
一.隔离级别理解 1.脏读 首先理解,一个事务对数据进行了改变,尽管该事务尚未提交,但此时其他事务中的查询语句(注意一定是处于事务中的语句,不处于事务中的语句查到的是正常的)查到的数据,是该事务修改之 ...
- spring中获取applicationContext
常用的5种获取spring 中bean的方式总结: 方法一:在初始化时保存ApplicationContext对象代码:ApplicationContext ac = new FileSystemXm ...
- Spring中AOP相关源码解析
前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...
随机推荐
- scrapy--多爬虫
大家好,我胡汉三又回来了!!!开心QAQ 由于最近一直在忙工作的事,之前学的一些爬虫知识忘得差不多了,只能再花多一些时间来回顾,否则根本无法前进.所以在这里也像高中老师那样提醒一下大家,--每天晚上花 ...
- #Python编程从入门到实践#第三章笔记
列表简介 1.什么是列表 列表:由一系列按也顶顺序排列的元素组成.元素之间可以没有任何关系. 列表:用方括号[]表示,并用逗号分隔其中元素.名称一般为复数 2.访问元素 (1)列表是有序集合 ...
- 使用selenium模拟登录知乎
网上流传着许多抓取知乎数据的代码,抓取它的数据有一个问题一定绕不过去,那就是模拟登录,今天我们就来聊聊知乎的模拟登录. 获取知乎内容的方法有两种,一种是使用request,想办法携带cookies等必 ...
- 493. Reverse Pairs
// see more at https://www.youtube.com/watch?v=j68OXAMlTM4 // https://leetcode.com/problems/reverse- ...
- sigaction函数
sigaction函数是设置信号处理的接口.比signal函数更健壮 #include <signal.h> int sigaction(int signum, const struct ...
- 用Go实现RabbitMQ消息收发
// amqp.Dial accepts a string in the AMQP URI format and returns a new Connection over TCP using Pla ...
- 笔记-python-standard library-11.2 os.path
笔记-python-standard library-11.2 os.path 1. os.path Source code: Lib/posixpath.py (for POSIX), L ...
- 15,redis基础学习
redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件 yum安装redis 1.yum安装 #前提得配置好阿里云yum源,epel源 #查看 ...
- 关于safaire下hash前面需要加/(正斜杠)
就是我们1.1框架是根据hash跳转的,今天我2.0跳转到1.1,pc一直测下来都是好的, 然后发现手机上一直跳转有问题,然后排查了半小时左右才发现 hash前面需要加/ 分割. 例如:http:/ ...
- 通过slf4j/log4j的MDC/NDC 实现日志追踪
在分布式系统或者较为复杂的系统中,我们希望可以看到一个客户请求的处理过程所涉及到的所有子系统\模块的处理日志. 由于slf4j/log4j基本是日志记录的标准组件,所以slf4j/log4j成为了我的 ...