Java标准资源定位

在Java标准资源管理中有面向资源的文件系统、artifact以及远程资源(HTTP、FTP等)。它们对应Java中的ClassLoader#getResource、File以及URL或者URI。

Spring为什么要另起炉灶搞一套资源定位呢?

主要是因为Java的标准资源定位不统一,分散到不同的API中。Spring有自己的野心,他想通过自定义一套API来进行整合,忽略底层的实现差异。事实上Spring也完成了这个目的,那就是其定义的Resource接口。

该接口有三个主要的实现类,分别为ClassPathResource、FileSystemResource、UrlResource,分别对应Java的ClassLoader、File以及URL。

Talk is cheap. Show me the code

第一步:分别使用ClassPathResource、FileSystemResource以及UrlResource来进行类路径下资源、磁盘上的资源以及网络资源进行测试。这里借助apache的commons-io包中的IOUtils的toString方法来输出资源内容。

package com.tech.resources;import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;import java.io.IOException;
import java.io.InputStream;public class SpringResourcesManagementDemo {public static void main(String[] args) throws IOException {// 类路径资源管理 对应 JDK的 ClassLoaderResource classPathResource = new ClassPathResource("default.properties");print(classPathResource.getInputStream());System.out.println("------------------------------分隔符---------------------------------");// 文件系统资源管理 对应 JDK的 FileResource fileSystemResource = new FileSystemResource("D:\\develop\\workSpace\\Coding\\" +"spring-framework-5.0.x\\esign-spring\\src\\main\\resources\\default.properties");print(fileSystemResource.getInputStream());System.out.println("------------------------------分隔符---------------------------------");// 面向流式资源管理 对应JDK的URL。这里指向的网络资源为我的博客地址Resource urlResource = new UrlResource("https://blog.csdn.net/m0_43448868/article/details/112254608");print(urlResource.getInputStream());}private static void print(InputStream is) throws IOException {try {Assert.state(is != null, "输入流不能为空!");System.out.println(IOUtils.toString(is, "UTF-8"));} catch (IOException ex) {throw ex;} finally {if (is != null) {is.close();}}}}

第二步:启动main方法查看控制台输出。

name=zhangSan
basePackages=com.xxx.spring
------------------------------分隔符---------------------------------
name=zhangSan
basePackages=com.xxx.spring
------------------------------分隔符---------------------------------<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><link rel="canonical" href="https://blog.csdn.net/m0_43448868/article/details/112254608"/><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"><meta name="report" content='{"pid": "blog", "spm":"1001.2101"}'><meta name="referrer" content="always"><meta http-equiv="Cache-Control" content="no-siteapp" /><link rel="alternate" media="handheld" href="#" /><meta name="shenma-site-verification" content="5a59773ab8077d4a62bf469ab966a63b_1497598848"><meta name="applicable-device" content="pc"><link  href="https://g.csdnimg.cn/static/logo/favicon32.ico"  rel="shortcut icon" type="image/x-icon" /><title>阿里面试题:什么是循环依赖?Spring是如何解决循环依赖的?_君战-CSDN博客</title><script>

可以看到无论是类路径下的资源还是磁盘中的资源以及网络资源都成功获取到了。

源码分析

ClassPathResource。这里我们只需要分析ClassPathResource的getInputStream方法即可,研究其是如何获取资源的。

// ClassPathResource#getInputStream
public InputStream getInputStream() throws IOException {InputStream is;if (this.clazz != null) {// 首先尝试使用传入的class的类加载器is = this.clazz.getResourceAsStream(this.path);} else if (this.classLoader != null) {// 其次尝试使用传入的类加载器is = this.classLoader.getResourceAsStream(this.path);} else {// 最后,尝试使用ClassLoaderis = ClassLoader.getSystemResourceAsStream(this.path);}if (is == null) {throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");}return is;
}

FileSystemResource。

// FileSystemResource#getInputStream
public InputStream getInputStream() throws IOException {try {// 这里使用NIO中的Files工具类来创建一个ChannelInputStreamreturn Files.newInputStream(this.filePath);}catch (NoSuchFileException ex) {throw new FileNotFoundException(ex.getMessage());}
}

UrlResource。

// UrlResource#getInputStream
public InputStream getInputStream() throws IOException {URLConnection con = this.url.openConnection();// 通过URL的openConnection方法来建立连接ResourceUtils.useCachesIfNecessary(con);try {return con.getInputStream();}catch (IOException ex) {// Close the HTTP connection (if applicable).if (con instanceof HttpURLConnection) {((HttpURLConnection) con).disconnect();}throw ex;}
}

附录

Apache commons-io maven依赖。

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>

default.properties

name=zhangSan
basePackages=com.xxx.spring

展望Spring野心-Spring资源定位相关推荐

  1. Spring MVC:资源

    我从博客读者那里收到的最常见的问题之一是如何在Spring MVC的应用程序中使用CSS和javascript文件. 因此,这是撰写有关Spring MVC中资源使用情况的文章的好机会. 通常,我将使 ...

  2. Spring Boot集成Ueditor富文本编辑器,实现图片上传,视频上传,返回内容功能并且通过OSS转换为链接并且解决Spring Security静态资源访问以及跨域问题

    学习自https://cloud.tencent.com/developer/article/1452451 现在是晚上22点,刚刚和我们的前端交流完了富文本编辑器的一些意见和看法 还是老样子 需求 ...

  3. Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程G

    第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...

  4. Spring - Java/J2EE Application Framework 应用框架 第 5 章 Spring AOP: Spring之面向方面编程

    第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层 ...

  5. 第 5 章 Spring AOP: Spring之面向方面编程

    http://oss.org.cn/ossdocs/framework/spring/zh-cn/aop.html 第 5 章 Spring AOP: Spring之面向方面编程 5.1. 概念 面向 ...

  6. 【Spring】Spring Bean 生命周期

    文章目录 1.概述 1.概述 出自:<深入浅出Spring Boot 2.x.pdf> 有时候我们也需要自定义初始化或者销毁 Bean 的过程,以满足一些 Bean 特殊初始化和销毁的要求 ...

  7. 项目从Spring转到SpringBoot Migrating from Spring to Spring Boot

    原文链接:Migrating from Spring to Spring Boot 1. Overview 概述 In this article, we're going to take a look ...

  8. springcloud:大话Spring Cloud,Spring Cloud是什么鬼?

    文章结尾有彩蛋 研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Cloud从技术架构上 ...

  9. Spring、Spring MVC、Spring boot、Spring Cloud面试题(史上最全面试题,精心整理100家互联网企业,面试必过)

    最全面试题,精心整理100家互联网企业面经,祝你面试成功.面试必过(2023优化版)已发布在个人微信公众号[面向Offer学编程],优化版首先修正了读者反馈的部分答案存在的错误,同时根据最新面试总结, ...

  10. 手动创建Spring项目 Spring framework

    之前学习框架一直是看的视频教程,并且在都配套有项目源码,跟着视频敲代码总是很简单,现在想深入了解,自己从官网下载文件手动搭建,就遇到了很多问题记载如下. 首先熟悉一下spring的官方网站:http: ...

最新文章

  1. HDU - 5876 Sparse Graph(bfs+set)
  2. html怎样添加css样式,html添加css样式的方法
  3. 批处理获取exe返回结果
  4. stl vector 函数_vector :: crend()函数以及C ++ STL中的示例
  5. 广义表的基本概念【数据结构】
  6. 简述php语言的特点是_PHP语言有哪些优势和特点(一)
  7. 随想录(虚拟机实现)
  8. 科学家对医疗预印本服务器的影响,美国化学学会将启动化学论文预印本服务
  9. 面经——小马智行2022秋招嵌入式
  10. python ios自动化_【Mac + Appium + Python3.6学习(三)】之IOS自动化测试环境配置
  11. mysql 主从复制延迟_什么情况会导致MySQL主从复制延迟?
  12. MFC Windows 程序设计(一)-程序员的解放
  13. 全面了解小微信贷风控
  14. CIR 工业自动化雷达
  15. ESP32 485光照度
  16. Python的堆与优先队列
  17. Matlab_GUI gcf、gca 以及gco 的区别用法
  18. Linux---挂载和卸载移动硬盘、开机自启动机械硬盘
  19. Linux(日志管理)
  20. R语言|散点图 ———R语言数据可视化系列(一)

热门文章

  1. C/C++[codeup 2025]比较字符串
  2. 网络中的网络 NiN 动手学深度学习v2 pytorch
  3. 翻译:Swift中的Operations和OperationQueues入门
  4. 足球比赛两强相遇概率
  5. 返回信息是html的性能测试,Web前端性能测试小点
  6. linux mysql 开发_Linux64下mysql安装和开发
  7. stm32通讯协议编写源码_STM32连接TFT-LCD
  8. 服务器上Jupyter notebook环境搭建
  9. 现代通信原理2.3:为什么我们这么关注傅立叶变换?
  10. K8S学习笔记之MiniKube的搭建(VM虚拟机环境)