使用 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>
使用下面的代碼,可以拿到類的代碼的路徑:
如: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/