zoukankan      html  css  js  c++  java
  • JDK 之资源文件管理

    JDK 之资源文件管理

    JDK 规范目录(https://www.cnblogs.com/binarylei/p/10200503.html)

    一、文件资源

    • user.home 用户目录,如 Linux 上 root 的用户目录为 /root
    • user.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 实现:

    1. Java 9 Flow API
    2. RxJava Reactive Extension Java
    3. 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

    参考:

    1. 《JavaBean 以及内省技术详解》:https://www.cnblogs.com/yejiurui/archive/2012/10/06/2712693.html

    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    长沙集训day6
    长沙集训day5(总结)
    长沙集训day4(总结)(爆零记)
    长沙集训day3(总结)(爆零记)
    长沙集训day2(总结)
    长沙集训day1(总结)
    p1324 dining(晚餐)
    p1156集合删数
    1034: [ZJOI2008]泡泡堂BNB
    清北学堂Day 6 游记
  • 原文地址:https://www.cnblogs.com/binarylei/p/10217351.html
Copyright © 2011-2022 走看看