展望Spring野心-Spring资源定位

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的 ClassLoader
		Resource classPathResource = new ClassPathResource("default.properties");
		print(classPathResource.getInputStream());

		System.out.println("------------------------------分隔符---------------------------------");
		// 文件系统资源管理 对应 JDK的 File
		Resource 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 {// 最后,尝试使用ClassLoader
		is = 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工具类来创建一个ChannelInputStream
		return 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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值