SpringBoot 的 jar 包及应用配置文件加载
SpringBoot 打包
如果你手动使用 jar 命令打过 jar 包(如下图)
那么一定知道该 jar 包与使用 spring-boot-maven-plugin 插件打出来的 jar 包(如下图)不一样。
SpringBoot 运行 jar 包
执行 java -jar xx.jar
命令时,会去解析 MATE-INF 文件夹中的 MANIFEST.MF 清单文件,然后找到 Main-class ,反射运行其中的 main
方法。这个是最根本的原因。
而 spring-boot-maven-plugin 插件打包后的 jar 包结构有所变动,新增 org loader 代码目录和 BOOT-INF 目录,META-INF 目录不变,但是其中的 MANIFEST.MF 发生改变,其中新增 Start-Class 表示真正的启动类,而原本的 Main-Class 则指向 JarLauncher
, JarLauncher
启动时会去注册协议,创建 ClassLoader
,加载并反射运行 Start-Class 中的 main
方法,来启动程序。重写 Jar 协议是在 SpringBoot loader 源码中的 JarFile
中进行的,同时重新实现 URLStreamHandler
来解决嵌套 Jar 的问题。
配置文件读取
未使用配置中心
java -jar xx.jar
启动的时候会找指定的 profile,开发和测试环境部署到 K8s 后没有指定 ConfigMap,使用的是 jar 包内的 application.yaml 和 application-dev.yaml。
生产环境基础的配置使用的也是 jar 包里的 application.yaml,但是配置了 ConfigMap,其内容就是 application-test.yaml,所以加在这个 yaml 里的配置需要写到发布文档中,在 application.yaml 变更的配置不需要写到发布文档中。
使用配置中心
如果微服务已经接入 Nacos,用的是 SpringCloud 的 bootstrap.yaml(指定使用哪个环境以及服务名称),具体的配置已经放到 Nacos 中,如 xx-service-dev.yaml(包含 application.yaml 和 application-test.yaml 的内容),变更的配置都需要写到发布文档中。
无论哪种方式,为了安全,账号密码等都需要配置在 ConfigMap 中。
参考资料
【Java 基础】Jar 包结构结构分析和操作详解
终于搞懂了 SpringBoot jar 包启动的原理
为什么 SpringBoot 可以直接运行 jar 包?
详解 java -jar 命令及 SpringBoot 通过 java -jav 启动的过程