zoukankan      html  css  js  c++  java
  • SpringBoot jar in jar 加载资源的原理及带来的问题

    使用 IDEA 运行 springboot 程序与 java -jar 运行 springboot 程序时 ClassLoader 不同,导致 classloader.getResource() 拿不到资源

    使用 this.getClass().getClassLoader() 获取 classloader 时,运行方式不同,结果不一样

    使用 IDEA 运行 springboot 程序时,sun.misc.Launcher$AppClassLoader@18b4aac2  
    使用 java -jar 运行打包后的 jar 包时,org.springframework.boot.loader.LaunchedURLClassLoader@71dac704
    LaunchedURLClassLoader 在以下 jar 包依赖中:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-loader</artifactId>
    </dependency>
    View Code

    使用下面的代码,可以拿到类的代码的路径:
    如:jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class 

    ProtectionDomain protectionDomain = getClass().getProtectionDomain();
    CodeSource codeSource = protectionDomain.getCodeSource();
    URI location = (codeSource == null ? null : codeSource.getLocation().toURI());

    对于原始的JarFile URL,只支持一个'!/',SpringBoot 扩展了此协议,使其支持多个'!/',以实现 jar in jar 的加载资源方式。

    但是,取到了资源路径,原生的 new File() 还是处理不了这种资源路径的。

    我们通过传统的方式取不到资源了,即使取到了,也没法直接使用,那在 SpringBoot 中我们应该怎么获取资源呢?
    可以参考 MyBatisPlus 中对 xml 文件的处理:com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties#mapperLocations  (有待研究)

    classloader不同引发的错误现象:https://blog.csdn.net/qq_38366063/article/details/97382500
    LaunchedURLClassLoader 原理:https://segmentfault.com/a/1190000013532009
    spring-boot-load 原理:https://www.jianshu.com/p/bedf5f3a2ad9
    springboot classload 的继承关系和影响:http://hengyunabc.github.io/spring-boot-classloader/

    http://hengyunabc.github.io/spring-boot-classloader/

  • 相关阅读:
    对坐标点的离散化
    线段树-离散化处理点
    树状数组
    线段树
    dfs
    vector
    go 参数传递的是值还是引用 (转)
    go 数组指针 指针数组
    go 协程
    go 接口实现
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/13169234.html
Copyright © 2011-2022 走看看