JDK 之资源文件管理
JDK 规范目录(https://www.cnblogs.com/binarylei/p/10200503.html)
一、文件资源
user.home
用户目录,如 Linux 上 root 的用户目录为 /rootuser.dir
项目工作目录
二、类路径资源
三、网络资源
java.net 包下有几个核心的类:
URL
URLConnection
URLStreamHandler
URLStreamHandlerFactory
通过 URLStreamHandlerFactory 获取 URLStreamHandler,通过这个 Handler 获取 URLConnection,进而操作各种网络资源。
JDK 1.8 中 URLStreamHandlerFactory 有一个默认的实现类 Factory,这个类是 Launcher 的内部类,代码如下:
private static URLStreamHandlerFactory factory = new Factory();
private static class Factory implements URLStreamHandlerFactory {
private static String PREFIX = "sun.net.www.protocol";
public URLStreamHandler createURLStreamHandler(String protocol) {
String name = PREFIX + "." + protocol + ".Handler";
try {
Class<?> c = Class.forName(name);
return (URLStreamHandler)c.newInstance();
} catch (ReflectiveOperationException e) {
throw new InternalError(e);
}
}
}
可以看到 JDK 默认加载 sun.net.www.protocol 包下的网络协议,JDK 默认已经实现了 jar、file、ftp、http、https 等。那如何扩展自定义协议呢?
3.1 自定义网络资源处理器
package sun.net.www.protocol.classpath;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
/**
* 自定义网络资源处理器,注意包名是 sun.net.www.protocol. + 协议名
*/
public class Handler extends URLStreamHandler {
private final static String PROTOCOL_PREFIX = "classpath:/";
@Override
protected URLConnection openConnection(URL u) throws IOException {
String urlString = u.toString();
urlString = urlString.substring(PROTOCOL_PREFIX.length());
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return classLoader.getResource(urlString).openConnection();
}
}
测试:
@Test
public void test3() throws Exception {
URL url = new URL("classpath:/spring-context-01.xml");
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
String content = IOUtils.toString(inputStream, Charset.forName("utf-8"));
System.out.println(content);
}
补充:JDK 中 classpath 问题
JDK 启动时 Launcher 创建了 Factory 对象,并将这个对象传递到了 ExtClassLoader 和 AppClassLoader 中。
public ExtClassLoader(File[] dirs) throws IOException {
super(getExtURLs(dirs), null, factory);
}
AppClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent, factory);
}
所以可以通过 classpath 获取对应的资源文件, JDK 内部实际上通过 factory 获取对应的资源文件,一般是 jar 协议 ,如何证明这一点呢?我们做个实验:
public void test() {
URL fileUrl = getClass().getResource("/spring-context-01.xml");
URL jarUrl = getClass().getResource("/META-INF/license.txt");
// file:/F:/doc/java/code-2018/spring/target/classes/spring-context-01.xml
System.out.println(fileUrl);
// jar:file:/D:/Program_Files/Maven/LocalRepository/org/springframework/spring-core/5.1.0.RELEASE/spring-core-5.1.0.RELEASE.jar!/META-INF/license.txt
System.out.println(jarUrl);
}
四、JDK 资源管理在 Spring 中的应用
Resource
ResourceLoader
ProtocolResolver
并发编程 Reactive Stream(一)Reator
本篇主要涉及到的是 java.util.concurrent 包中的 ExecutorService。ExecutorService 就是 Java 中对线程池的实现。
时代的局限性(JKD 9 之前)
阻塞编程:无法并行计算,资源低效使用
异步编程:Callback Future
数据方向:
Reactive Streams: 推模式(Push)
Iterator: 拉模式(Pull)
编程模式
Reactive Streams: 发布订阅模式(Publish-Subscriber)
Iterator: 命令式编程模式(Imperative)
onSubscribe() 订阅事件
onNext() 订阅事件
onComplete() 订阅事件
onError() 订阅事件
request() 订阅事件
cancel() 订阅事件
Mono 异步 0-1 元素序列,Futrue<Optional<?>>
Flux 异步 0-N 元素序列,Futrue<Collection<?>>
Reactive Stream 实现:
- Java 9 Flow API
- RxJava Reactive Extension Java
- Reacotr Reactor Framwork
Java 5 前时代
Java Green Thread
Java Native Thread
编程模型
Thread
Runable
缺少线程管理的原生支持
缺少执行完成的原生支持执行
结果获取困难
缺少“锁”API
Double Check Locking不确定性
Java 5 时代
JUC
编程模型
Executor
Runable Callable
Future
Java 7 异步并行框架
Fork/Join
编程模型
ForkJoinPool
ForkJoinTask
RecursiveActive
Future的限制无法手动完成
阻塞式结果返回
无法链式多个 Future
无法合并多个 Futures结果
缺少异常处理
Java 8 异步并行框架
Fork/Join
编程模型
CompletionStage
CompletionFuture
参考:
- 《JavaBean 以及内省技术详解》:https://www.cnblogs.com/yejiurui/archive/2012/10/06/2712693.html
每天用心记录一点点。内容也许不重要,但习惯很重要!