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;
- }
转载于:https://www.cnblogs.com/1995hxt/p/5800257.html
classpath: spring 中的查找方式相关推荐
- Spring中使用XML方式导入Spring配置文件,Boot中使用全注解导入Spring配置
目录 Spring中的方法 Spring Boot中的方法 Spring中的方法 @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效: Spring Boot里面没有 ...
- spring中依赖注入方式总结
文章来源于今日头条用户:分布式系统架构 一.注解注入 注解注入在Spring中是用的最多的一种方式,就是在java代码中使用注解的方式进行装配,在代码中加入@Resource或者@Autowired. ...
- java之spring中时间戳转换时间方式
1.来一组老手艺先,这是比较传统的方法也就是纯Java写的. @GetMapping("/j2")//@ResponseBody 不走视图解析器的情况,但是上面的注解代表已经含有不 ...
- Spring中你不知道的注入方式
前言 在Spring配置文件中使用XML文件进行配置,实际上是让Spring执行了相应的代码,例如: 使用<bean>元素,实际上是让Spring执行无参或有参构造器 使用<prop ...
- Spring中IoC创建对象方式(构造器注入)
Ioc创建对象的方法分为无参构造创建和有参构造创建,首先看无参构造,也是Spring默认实现 这里给出一个User实体类 package com.zhiying.pojo;public class U ...
- Spring中加载xml配置文件的六种方式
Spring中加载xml配置文件的六种方式 博客分类: Spring&EJB XMLSpringWebBeanBlog 因为目前正在从事一个项目,项目中一个需求就是所有的功能都是插件的形式装 ...
- spring中事务配置的3种方式-2
http://doc.javanb.com/spring-framework-reference-zh-2-0-5/ch09s05.html http://zpchen.iteye.com/blog/ ...
- Spring中配置Hibernate事务的四种方式
2019独角兽企业重金招聘Python工程师标准>>> 为了保证数据的一致性,在编程的时候往往需要引入事务这个概念.事务有4个特性:原子性.一致性.隔离性.持久性. 事务的种类有两种 ...
- Spring依赖注入的方式、类型、Bean的作用域、自动注入、在Spring配置文件中引入属性文件...
1.Spring依赖注入的方式 通过set方法完成依赖注入 通过构造方法完成依赖注入 2.依赖注入的类型 基本数据类型和字符串 使用value属性 如果是指向另一个对象的引入 使用ref属性 User ...
最新文章
- 基于Hadoop的大数据平台实施记——整体架构设计[转]
- Sublime和Webstorm新建代码块
- 中国SaaS人力资源管理系统市场发展模式分析与前景深度研究报告2022年版
- 防止电脑自动休眠小妙招
- hdu 4686 Arc of Dream
- linux发送http请求xml报文,使用curl命令行发送/发布xml文件
- 大牛唐健,带你领略游戏服务器与后台架构的奥妙
- POJ 3436 -- ACM Computer Factory(最大流,建图)
- 蚂蚁金服井贤栋:区块链和人工智能是影响未来的关键技术
- 窗体跳转与传值 02
- 物联网操作系统 - Contiki
- linux查看硬件信息及驱动设备
- 比赛评分公开展示系统_[评委计分系统v3-双屏标准版]与[评委计分系统v3-双屏专业版]的差异
- 遇到Python中文目录名问题,未解决
- 通达OA2015 数据选择控件的使用随笔
- tcp流式传输_收听互联网广播以及下载和流式传输免费音乐的最佳网站
- 典型的对称加密和非对称加密算法有哪些
- 统计建模与R软件 薛毅 陈立萍 清华大学出版社第四章课后答案
- 关于unity场景切换后模型变黑问题
- Python基础知识——字典:for循环遍历字典
热门文章
- 【编译原理】第二章课后习题(王生原版)
- 回溯法解整数的划分问题(C语言)
- impdp导入表结构和表数据_ORACLE数据库如何用datapump工具导出表结构然后导入到其它Schema下面...
- [图神经网络] 图节点Node表示---GraphSAGE与PinSAGE
- 强化学习 求解迷宫问题_使用天真强化学习的迷宫求解器
- 哪些贷款是正规的?哪些贷款千万别碰?
- 看日本雅-miyavi演唱会
- “天下第一长联”与“元跨革囊”
- 解决GetManifestResourceNames()无法读取资源文件
- Power of Three