创建独立的Spring应用作为Spring Boot的首要特性。
- 为什么需要独立的应用?
Spring Boot应用无需像传统的Java EE那样将应用打包成WAR或者EAR包,并部署到Java EE容器中。
Spring Boot应用采用嵌入式容器,独立于外部容器,对应用生命周期拥有完全自主的控制 - 为什么为Spring应用而非Spring Boot应用
当Spring Boot的嵌入式容器成为应用的一部分,从本质上来说,属于Spring应用上下文中的组建Beans,由自动装配特性组装成Spring Bean定义,随Spring应用上下文启动而注册并初始化。启动上下文的核心组件是Spring Boot核心API SpringApplication
创建Spring Boot项目
CMD命令行模式创建
略
图形化界面创建Spring Boot应用
Spring官方提供的在线创建 https://start.spring.io/
IDE集成创建
例如idea
Spring Boot模版目录
简单选择了几个常用的框架组建后如上图,其包含如上图结构
- .gitignore文件
引入该文件的目的是因为Git作为大多数代码版本控制,定义了最常见的文件或目录的版本控制忽略文件 - Maven Wrapper文件
包含.mvn目录、执行脚本mvnw和mvnw.cmd
1.Maven Wrapper是一种简单的Maven构建方式,运行环境不需要提前安装Maven二进制文件
2.jar由脚本引导,用于从Maven官方下载Maven二进制文件
3.properties定义文件下载URL
4.mvnw、mvnw.cmd引导jar的unix-like的shell脚本和win脚本 - Spring Boot应用属性配置文件-application.properties
Spring Boot默认的应用外部配置文件 - Spring Boot应用测试文件
提供Spring Boot集成测试的基本模式
创建Spring Boot应用可执行JAR
构建可执行JAR的前提需要在pom中添加spring-boot-maven-plugin。
如果通过 https://start.spring.io/ 构建项目则默认添加该插件
且默认继承自spring-boot-starter-parent 所以不需要指定Maven依赖和插件的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
运行Spring Boot应用
java --help
用法: java [-options] class [args...]
(执行类)
或 java [-options] -jar jarfile [args...]
(执行 jar 文件)
执行Spring Boot应用可执行JAR
- java -jar
- mvn spring-boot:run
二者命令基本无差异,运行速度也不熟影响,前者多用于生产环境运行方式,后者为开发阶段运行方式
Spring Boot应用可执行Jar资源结构
***.jar.original属于原始Maven打包JAR文件
***.jar是被spring-boot-mavven-plugin Mven插件加功引入相关第三方依赖资源后的JAR文件
Spring Boot打包后的JAR文件在模仿Java EE的WAR文件结构
FAT JAR 和WAR执行模块——spring-boot-loader
Java官方规定 java -jar 命令引导的具体启动类必须配置在MANIFEST.MF资源的Main-Class属性中,且放置在/META-INF/目录下
Manifest-Version: 1.0
Implementation-Title: ***
Implementation-Version: ***
Start-Class: ****
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.7.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.PropertiesLauncher
其main class为org.springframework.boot.loader.PropertiesLauncher。
https://docs.spring.io/spring-boot/docs/2.5.0-SNAPSHOT/reference/html/appendix-executable-jar-format.html#executable-jar-property-launcher-features
有三种启动器
org.springframework.boot.loader.JarLauncher
org.springframework.boot.loader.WarLauncher
org.springframework.boot.loader.PropertiesLauncher
分别启动JAR包,WAR包和设置外部属性启动
可执行JAR文件启动器:JarLauncher
org.springframework.boot.loader.JarLauncher并非项目中的文件,由插件spring-boot-maven-plugin追加进去的。
导入依赖坐标,或者解压打包好的Spring Boot项目jar可以查看到相关信息
可以通过解压jar包后,直接java运行该类也可以启动项目
JarLauncher的实现原理
public class JarLauncher extends ExecutableArchiveLauncher {
static final String BOOT_INF_CLASSES = "BOOT-INF/classes/";
static final String BOOT_INF_LIB = "BOOT-INF/lib/";
public JarLauncher() {
}
protected JarLauncher(Archive archive) {
super(archive);
}
protected boolean isNestedArchive(Entry entry) {
return entry.isDirectory() ? entry.getName().equals("BOOT-INF/classes/") : entry.getName().startsWith("BOOT-INF/lib/");
}
public static void main(String[] args) throws Exception {
(new JarLauncher()).launch(args);
}
}
mainClass类名字来自/META-INF/MANIFEST.MF的Start-Class属性,且子类并未覆盖该方法。无论JAR或者WAR读取的Spring Boot启动类均来自此属性
可执行WAR文件启动器:WarLauncher
Warlauncher与JarLauncher的差异较小,主要区别在于项目文件和Jar Class Path路径不同
public class WarLauncher extends ExecutableArchiveLauncher {
private static final String WEB_INF = "WEB-INF/";
private static final String WEB_INF_CLASSES = "WEB-INF/classes/";
private static final String WEB_INF_LIB = "WEB-INF/lib/";
private static final String WEB_INF_LIB_PROVIDED = "WEB-INF/lib-provided/";
public WarLauncher() {
}
protected WarLauncher(Archive archive) {
super(archive);
}
public boolean isNestedArchive(Entry entry) {
if (entry.isDirectory()) {
return entry.getName().equals("WEB-INF/classes/");
} else {
return entry.getName().startsWith("WEB-INF/lib/") || entry.getName().startsWith("WEB-INF/lib-provided/");
}
}
public static void main(String[] args) throws Exception {
(new WarLauncher()).launch(args);
}
}
由于打包后的文件目录存放不同。
传统的WEB-INF/lib-provided的JAR将被Servlet容器忽略,如Servlet API。
打包后的WAR文件能够在Servlet容器中兼容运行。
打包WAR文件是一种兼容措施,技能被WarLauncher启动,又能兼容Servlet容器环境。WarLauncher与JarLauncher并无被指差别。Spring Boot应用使用非传统Web部署时,尽可能使用JAR归档方式。
JAR和WAR归档应用均为Spring Boot独立应用
Comments | 0 条评论