知识杂货铺 知识杂货铺
首页
后端(1本书)
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 核心配置和约定
  • 自动生成front matter
  • Markdown 容器
  • Markdown 中使用组件
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
    • 在线编辑和新增文章的方法
  • 主题配置
  • 首页配置
  • front matter配置
  • 目录页配置
  • 添加摘要
  • 修改主题颜色和样式
  • 评论栏
  • 快速开始
  • 代码集成_TODO
  • 框架初探
  • 在GitHub上贡献代码
  • 使用K8s部署系统
  • Seata分布式事务
GitHub (opens new window)

Kevin Zhang

爱凑热闹的高龄程序猿
首页
后端(1本书)
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 核心配置和约定
  • 自动生成front matter
  • Markdown 容器
  • Markdown 中使用组件
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
    • 在线编辑和新增文章的方法
  • 主题配置
  • 首页配置
  • front matter配置
  • 目录页配置
  • 添加摘要
  • 修改主题颜色和样式
  • 评论栏
  • 快速开始
  • 代码集成_TODO
  • 框架初探
  • 在GitHub上贡献代码
  • 使用K8s部署系统
  • Seata分布式事务
GitHub (opens new window)
  • Spring Boot 培训教程
  • Spring Boot介绍

  • 开发环境配置

  • 原理剖析

  • Web开发

  • 数据访问

  • 事务

  • 集成Redis

  • 集成MongoDB

  • 异步消息

  • 异常处理

  • 单元测试与热部署

  • 安全控制

  • 应用监控

  • 企业级开发

  • 多环境配置与部署

    • 多环境配置与部署
    • 多环境配置
    • 打包部署应用
      • 15.2 打包部署应用
        • 15.2.1 Fat JAR
        • 15.2.2 WAR
    • 课后作业
  • 综合示例

  • 前后端分离的vue急速入门

  • Spring Boot配置大全

  • 在Docker中部署Spring Boot应用

  • 开发前后端分离应用

  • 前进到Spring Cloud

  • 规则引擎

  • 流程引擎

  • 后记
  • 后端
  • 多环境配置与部署
Kevin Zhang
2024-10-30
目录

打包部署应用

# 15.2 打包部署应用

Spring Boot 项目可以如传统的 Web 应用一样打包成 war 包,部署到不同的应用服务器(如 tomcat,jetty,WebSphere Application Server,WebLogic 等)中,也可以使用内嵌服务器(tomcat,jetty,Undertow 等开源容器),以直接可运行的可执行 jar 包(Spring Boot 官方称之为 fat jar)方式部署。

由于我们在绝大多数情况下使用 Spring Boot 开发前后端分离的企业级应用,所以这里介绍的 Spring Boot 项目特指 Spring Boot Web 项目,即使用 Spring MVC 通过REST方式在 HTTP 上提供服务的后端项目。

本小节对这两种打包部署方式进行介绍。

官方文档 (opens new window)介绍,其支持 Maven 和 Gradle 两种构建系统,本小节只介绍我们在项目中经常使用的 Maven 构建系统。

在 Maven 构建系统中,Spring Boot 是通过 Maven 插件的方式提供打包支持的。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
1
2
3
4
5
6
7
8

# 15.2.1 Fat JAR

为了分析 Spring Boot Fat JAR 的启动机制,添加“spring-boot-loader”依赖,以便打开 Spring Boot 对应的源码。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-loader</artifactId>
    <scope>provided</scope>
</dependency>
1
2
3
4
5

在 Spring Boot 项目的 pom.xml 文件中指定项目打包类型为 jar(<packaging>jar</packaging>,不提供打包类型,默认就是打包为 jar),然后添加spring-boot-maven-plugin插件,在项目上运行 Maven Build...

image-20200131144147470

在 Goals 输入package 构建命令(可选跳过测试),然后运行。Maven 就开始编译打包。

在STS中新建 Spring Starter 项目,默认就添加了spring-boot-maven-plugin插件。

image-20200131142025288

Maven 打包完成后,在项目的 target 目录中就生成了两个 jar 包:

  • config-0.0.1-SNAPSHOT.jar.original:原始的 jar 包,包含项目代码编译后的内容;
  • config-0.0.1-SNAPSHOT.jar:spring-boot-maven-plugin 插件添加依赖的其他 jar 包(如内嵌 tomcat 服务器,Spring MVC,MySQL 驱动等)的“Fat Jar”文件。

image-20200131142129791

使用 WinRAR 压缩工具打开这个 Fat Jar 文件,可以看到在 BOOT-INF 下的 lib 子目录下包含了 tomcat 内嵌服务器及其他依赖 jar 包。在 BOOT-INF\classes 目录下就是我们在项目中配置文件、Java 类编译后的 class 字节码文件。

image-20200131144913756

├── BOOT-INF # 存放项目中开发的业务相关类和配置文件,和依赖的jar
│   ├── classes # 项目业务代码及配置文件
│   └── lib # 存放项目的依赖库,如Spring MVC,MySQL JDBC驱动,Tomcat内嵌服务器
├── META-INF # 包括 MANIFEST.MF 描述文件和 maven 的构建信息
│   ├── MANIFEST.MF
│   └── maven
└── org # Spring Boot 相关的类
    └── springframework
1
2
3
4
5
6
7
8

根据 Java jar 的运行规范,查看/META-INF/MANIFEST.MF,找到的Main-Class是org.springframework.boot.loader.JarLauncher,这是 Spring Boot 提供的一个启动类。

Manifest-Version: 1.0
Implementation-Title: spring-boot-config
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.example.config.SpringBootConfigApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.2.4.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher
1
2
3
4
5
6
7
8
9
10

image-20200131150539889

打开 JarLauncher 源码,可以看到其继承自 ExecutableArchiveLauncher 类,并提供了 "BOOT-INF/classes/" 和 "BOOT-INF/lib/" 常量。

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);
	}

	@Override
	protected boolean isNestedArchive(Archive.Entry entry) {
		if (entry.isDirectory()) {
			return entry.getName().equals(BOOT_INF_CLASSES);
		}
		return entry.getName().startsWith(BOOT_INF_LIB);
	}

	public static void main(String[] args) throws Exception {
		new JarLauncher().launch(args);
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

查看 ExecutableArchiveLauncher 类,可以看到 getMainClass 方法获取 Start-Class(/META-INF/MANIFEST.MF文件中提供的:Start-Class: com.example.config.SpringBootConfigApplication),这个就是我们在项目中用 @SpringBootApplication 注解标注的 SpringBootConfigApplication 启动类。

	@Override
	protected String getMainClass() throws Exception {
		Manifest manifest = this.archive.getManifest();
		String mainClass = null;
		if (manifest != null) {
			mainClass = manifest.getMainAttributes().getValue("Start-Class");
		}
		if (mainClass == null) {
			throw new IllegalStateException("No 'Start-Class' manifest entry specified in " + this);
		}
		return mainClass;
	}
1
2
3
4
5
6
7
8
9
10
11
12

简单的说,jar 包中的 Main-Class JarLauncher 找到 Start-Class(就是 @SpringBootApplication 注解标注的的启动类),使用 Fat JAR 文件中 BOOT-INF/lib/ 路径下的依赖 jar 包,运行 Spring Boot 应用程序。

一旦打包好了 Fat JAR,就可以 ssh 到工作机/堡垒机然后通过 scp 将这个 Fat JAR 拷贝到部署服务器上,通过nohup java -jar xxx.jar & 即可启动 Spring Boot 应用。以上几个命令,都为 Linux 下的命令。

本小节示例项目代码:

https://github.com/gyzhang/SpringBootCourseCode/tree/master/spring-boot-config (opens new window)

# 15.2.2 WAR

在较少遇到的一些特殊情况下,我们需要将 Spring Boot 后端项目打包部署到客户指定的服务器上,比如 WebSphere Application Server、WebLogic 上,这种传统部署方式就需要传统的 war 包。

Spring Starter 新建项目向导提供了完善的支持,可以快速的开发测试项目,并将项目打包为传统 war 包。

首先创建一个 Spring Boot 项目,打包类型选择“War”。

image-20200131170504335

选择 Spring Web 启动器依赖。

image-20200131170524454

Spring Starter 新建项目向导为项目 pom 文件中添加打包类型<packaging>war</packaging>和spring-boot-starter-tomcat依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>war</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>spring-boot-war</name>
	<description>Spring Boot War Example.</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

Spring 为我们生成了一个 ServletInitializer 类,在 configure 方法中完成初始化操作。

package com.example.war;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootWarApplication.class);
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13

在开发环境下可按照“Spring Boot App”方式正常运行,和传统内嵌 tomcat 容器运行方式一样。

image-20200131172725431

服务器启动后,访问http://localhost:8080/hello/greeting?name=Kevin (opens new window) 可按照预期返回结果。

image-20200131172106076

也可以在 STS 中添加 tomcat 9,然后选择“Run on Server”按照传统 Web 应用开发方式运行。

在 STS 内打开的浏览器地址栏中输入http://localhost:8080/war/hello/greeting?name=Kevin (opens new window) 可正确的返回期望的结果。

image-20200131175814160

执行 maven package 打包操作后,在项目 target 目录下生成两个 war 包文件,和传统内嵌web容器的 jar 包类似,一个为原始封包,一个为可运行 war 包。

image-20200131174041012

通过 WinRAR 打开 war-0.0.1-SNAPSHOT.war 文件,可以看到熟悉的 war 包结构和 Spring Boot 的 Fat JAR 的 org.springframework.boot.loader.JarLauncher 类等类似结构。

image-20200131174404243

查看“/META-INF/MANIFEST.MF”文件,可以看到 Main-Class 变更为 Main-Class: org.springframework.boot.loader.WarLauncher ,通过 java -jar war-0.0.1-SNAPSHOT.war 可运行内嵌服务器版的 Spring Boot war 应用。

Manifest-Version: 1.0
Implementation-Title: spring-boot-war
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.example.war.SpringBootWarApplication
Spring-Boot-Classes: WEB-INF/classes/
Spring-Boot-Lib: WEB-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.2.4.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.WarLauncher
1
2
3
4
5
6
7
8
9
10

将打包后的 war-0.0.1-SNAPSHOT.war 文件拷贝到“apache-tomcat-9.0.30\webapps”目录下,启动 tomcat,打开浏览器访问http://localhost:8080/war-0.0.1-SNAPSHOT/hello/greeting?name=Kevin (opens new window) 可正确的返回期望的结果。

image-20200131180159588

Spring Boot 为我们打包的 war 文件,即可单独运行(使用内嵌 web 容器),也可以部署到 web 服务器(如 tomcat 9)中运行。

所以,我们可以将 Spring Boot 打包出来的 war 包称之为 Fat WAR。

本小节示例项目代码:

https://github.com/gyzhang/SpringBootCourseCode/tree/master/spring-boot-war (opens new window)

编辑 (opens new window)
上次更新: 2024/11/17, 16:29:23
多环境配置
课后作业

← 多环境配置 课后作业→

最近更新
01
PNG图片处理C++
02-07
02
PNG图片处理
01-24
03
离线安装Docker
12-24
更多文章>
Theme by Vdoing | Copyright © 2008-2025 Kevin Zhang | MIT License | 蜀ICP备20013663号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式