Spring Boot 大家应该都知道如何启动。但是为什么通过main方法就能启动呢?请听我细细道来。
一般启动spring Boot 应用的方式有两种:
开发环境
@SpringBootApplication
public class FirstAppByGuiApplication {
public static void main(String[] args) {
SpringApplication.run(FirstAppByGuiApplication.class, args);
}
}
正式环境
java -jar xxx.jar
将一个 demo 项目打包 mvn package,得到的是一个xx.jar 和 xx.jar.original.jar .
JAR 文件有时候被称为“Fat JAR” ,采用zip压缩格式存储。
通过解压 unzip xx.jar -d temp
查看目录 tree temp/
-
BOOT-INF/classes 目录存放应用编译后的class文件;
-
BOOT-INF/lib 目录存放应用依赖的jar包;
-
META-INF/ 目录存放应用相关的元信息,比如MANIFESTR.MF
-
org/ 目录存放Spring Boot相关的class文件
xx.jar.original 是原始jar文件 结构目录 跟jar差异很大
-
除了 META-INF 文件 其余目录结构都发生了变化,并且 class 和 application.properties 都放在根目录下
打开 MANIFEST.MF ,发现 Main-Class 指向的是 org.springframework.boot.loader.JarLauncher,Start-Class 则为我们指定的引导类 thinking.in.spring.boot.firstappbygui.FirstAppByGuiApplication
Manifest-Version: 1.0
Implementation-Title: 《Spring Boot 编程思想》图形化构建 Sp
ring Boot 应用
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: xie87
Implementation-Vendor-Id: thinking-in-spring-boot
Spring-Boot-Version: 2.0.2.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: thinking.in.spring.boot.firstappbygui.FirstAppByGuiApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.3
Build-Jdk: 1.8.0_131
Implementation-URL: https://projects.spring.io/spring-boot/#/spring-bo
ot-starter-parent/first-app-by-gui
JarLauncher 为 spring-boot-loader 包中的启动器,loader 也是 spring-boot 中的核心包
为了验证上述的结果是正确的,通过 JarLauncher 启动
$ java org.springframework.boot.loader.JarLauncher
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.2.RELEASE)
....
2019-04-21 11:39:14.281 INFO 15072 --- [ main]
t.i.s.b.f.FirstAppByGuiApplication : Started FirstAppByGuiApplication in 5.573 seconds (JVM running for 6.383)
验证下通过 Application 能否启动
$ java thinking.in.spring.boot.firstappbygui.FirstAppByGuiApplication
错误: 找不到或无法加载主类 thinking.in.spring.boot.firstappbygui.FirstAppByGuiApplication
因为 java 指令没有指定 Class Path , 而当前的 Spring Boot 依赖的 Jar 文件均放在 BOOT-INF/lib 下。JarLauncher 会将这些 JAR 文件作为 FirstAppByGuiApplication 的类依赖库,所以 JarLauncher 能够引导成功。
JarLauncher 实现原理参考下篇文章:
Thinking In Spring Boot之Spring Boot 如何启动—JarLauncher实现原理(二)
参考文档:Spring Boot 官网文档 E.3.1 Launcher Manifest
原著:书名: Spring Boot 编程思想 作者:小马哥
Please enjoy the pain which is unable to avoid.
请享受无法回避的痛苦。