理解独立的Spring应用
在SpringBoot编程思想一书中,本章着重介绍了SpringBoot项目的命令行以及图形界面创建方式,SpringBoot项目、jar包、war包等的目录结构,以及最重要的SpringBoot应用是如何通过jar包以及war包方式运行的。
文章目录
创建SpringBoot项目
介绍了如何通过命令行中的maven命令来创建springboot项目以及spring官网的图形界面创建方式创建项目。并且使用maven的方式来编译运行项目(而不是jar包或war包)。
命令行创建
通过Maven Archetype插件(一种创建Maven模板项目的工具)来创建。
1.创建基本mvn项目
利用默认的基本mvn模板来创建一个基本的mvn项目。
mvn archetype:generate -DgroupId=cn.xxx -DartifactId=springboot-project -Dpackage=cn.xxx.springboot.project -Dversion=1.0.0 -DinteractiveMode=false
groupId:开发团队的统一标识,一般使用两段,第一段代表域,类似org、com、cn等,第二段代表公司名称或者团队名称。
artifactId:可以简单理解为实际的项目名称。
package:生成项目的默认包名,一般为GroupId+ArtifactId的组合。
version:版本号标识。
interactiveMode:是否为交互式创建。
2.添加SpringBoot依赖
在项目中的pom.xml文件中添加Spring Boot Web依赖以及Spring Boot Parent POM。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--添加SpringBoot Parent POM-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<groupId>cn.xxx</groupId>
<artifactId>springboot-project</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>springboot-project</name>
<url>http://maven.apache.org</url>
<dependencies>
<!--添加springboot web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3.添加启动代码
在自动生成的APP.java类上添加启动代码,使其成为启动类。
@RestController
@SpringBootApplication //主要启动注解
public class App {
@RequestMapping("/")
public String index() {
return "Welcome to my project!";
}
public static void main( String[] args ) {
SpringApplication.run(App.class,args); //主要启动代码
}
}
4.启动项目
在项目路径下使用mvn spring-boot:run
命令即可运行此项目。
图形化创建
在https://start.spring.io网站下即可快速的创建Spring Boot项目。
1.生成项目
在网站首界面填好group,artifact,以及添加dependencies中的web即可生成项目。
2.项目结构
src:
存放源码,测试源码,资源文件。
.gitignore:
定义了git的版本控制忽略名单。
.mvn、mvnw、mvnw.cmd:
简单的maven构建方式,无需在运行环境提前安装mavne二进制文件。
.mvn/wrapper
中的jar用于从maven官方下载maven二进制文件,properties文件在jar下载失败时,定义了下载的url。
mvnw和mvnw.cmd
为引导.mvn中的jar下载mvn二进制文件用的脚本,分别对应linux和windows平台。
3.启动项目
在linux平台下通过,sh mvnw spring-boot:run
命令即可下载maven并运行项目。
注:此启动方式属于开发环境启动方式,生产环境一般通过jar/war包方式启动。
创建并执行jar包
添加打包plugin到pom.xml
构建SpringBoot项目可执行jar包的前提是需要添加spring-boot-maven-plugin到pom.xml中。
注:图形化创建的项目中包含了此plugin,无需添加。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<groupId>cn.xxx</groupId>
<artifactId>springboot-project</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>springboot-project</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--添加SpringBoot的打包插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!---->
</project>
执行mvn打包命令
在项目路径下的命令行中执行mvn package
命令即可。
运行jar包
命令行执行java -jar jar包路径
即可运行此jar包。
SpringBoot中的Jar
jar包结构
在运行mvn打包命令后在项目的target/目录下会出现:
项目名-版本号.jar与项目名-版本号.jar.original两个文件。
项目名-版本号.jar.original
这个文件是mvn打包的原始jar文件
路径结构:
/类路径 储存的是编译后的class文件
/META-INF 储存的是元信息
项目名-版本号.jar
这个文件是original文件经过mvn加工后的jar包,引入了第三方依赖资源。
路径结构:
/BOOT-INF/classes 储存的是编译后的class文件
/BOOT-INF/lib 储存的是依赖的第三方jar包
/META-INF 储存的是元信息
/org 存放的是SpringBoot相关的class文件
与传统jar的区别
springboot项目经过mvn打包出来的jar包中除了META-INF与传统jar包相同外,其它结构与传统jar包并不相同,其结构更像传统的web项目的war包。
jar包是如何运行的
既然SpringBoot的jar包结构与传统jar包并不相同,那么java -jar命令是如何运行它的呢?
java -jar命令启动类配置文件
java -jar的引导启动类是配置在/META-INF/MANIFEST.MF文件中的 MAIN-Class属性中的。
SpringBoot项目jar包配置的jar启动引导类为:
Main-Class: org.springframework.boot.loader.JarLauncher
jar包引导类
MANIFEST.MF文件中配置的启动引导类正是在jar包的\org\springframework\boot\loader\路径下的JarLauncher.class类。
此类是由mvn pom中配置的plugin插件repackage jar.original时加入进去的。
JarLauncher类的职责:
引导并加载MAINIFEST.MF中配置的Start-Class类(也就是加springboot注解的那个springboot启动类)。
配置classpath,使BOOT-INF/lib下的第三方jar包能够被找到。
jar包引导类介绍
public class JarLauncher extends ExecutableArchiveLauncher {
static final String BOOT_INF_CLASSES = "BOOT-INF/classes/"; //类路径
static final String BOOT_INF_LIB = "BOOT-INF/lib/"; //第三方依赖jar路径
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/"); //判断是否以其开头来判断是jar包还是解压后的文件
}
public static void main(String[] args) throws Exception {
(new JarLauncher()).launch(args); //启动类引导
}
}
JarLauncher既支持jar包 也支持解压后的jar包运行。
JarLauncher在同进程内调用Start-Class类的main方法,并在启动前准备好ClassPath。
证明与源码分析请看书P41-P54页。
SpringBoot的War与Jar区别
WAR包结构
/WEB-INF/classes 储存的是编译后的class文件
/WEB-INF/lib 储存的是依赖的第三方jar包
/WEB-INF/lib-provided 储存的是pom中被provided的依赖
/META-INF 储存的是元信息
/org 存放的是SpringBoot相关的class文件
因为Sevlet容器只关心WEB-INF下的classes和lib,所以lib-provided会被忽略转而使用Servlet容器自带的api来实现,如Servlet API。
因此这样设计WAR包既可以通过WarLauncher引导运行,也可以在Servlet容器中运行。
的是依赖的第三方jar包Jar的类似,因此不再介绍,只有路径区别且WarLauncher会加载lib-provided中的依赖。