Spring Boot - Gradle 打包

引用

https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/gradle-plugin/reference/html/
http://swiftlet.net/archives/667
https://www.cnblogs.com/adolfmc/archive/2012/10/07/2713562.html
https://www.zhihu.com/question/22129866
https://josh-persistence.iteye.com/blog/1938520

本文 Spring Boot 版本为 2.1.0.RELEASE


jar 包 和 war 包

因水平有限 , 下列概念结合了上述引用的博客 ,是本人肤浅的理解 , 如有描述不当,请指正。

  • 普通 jar 包 : 会将源码编译后以工具包(即将class打成jar包)的形式对外提供,此时,你的 jar 包不一定要是可执行的,只要能通过编译,可以被别的项目以 import 的方式调用。
  • 可执行 jar 包 : 能通过 java -jar 的命令运行。
  • 普通 war 包 : war 是一个 web 模块,其中包括 WEB-INF,是可以直接运行的 WEB 模块。做好一个 web 应用后,打成包部署到容器中。
  • 可执行 war 包 : 普通 war 包 + 内嵌容器 。

可执行 jar

Spring boot 打可执行 jar 包 , 默认情况下, 直接打包即可 :

gradle  build 

打包成功后,文件默认生成路径在项目 build/libs 路径下 ,如:

web-0.0.1-SNAPSHOT.jar 

启动 :

java -jar  web-0.0.1-SNAPSHOT.jar  

可执行 war

可执行 war 包的意思是 : war 包中包含了应用的所有依赖 。你可以直接通过 java -jar 来启动 , 也可以将其部署到服务器(如 Tomcat )中 。
我们在使用 Spring Boot 开发的时候,并不需要额外配置服务器 , 因为 Spring Boot 默认使用了内嵌容器,如 Tomcat ,因此在打包的时候需要做额外处理 。
第一步 : 配置依赖

dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-web'
     providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' // 如果你使用的是 Tomcat , 添加此行。
}

上述 providedRuntime 确保内嵌的 Tomcat 服务器被打包到 WEB-INF/lib-provided 目录下。这样的好处是 : 如果你不想使用内嵌的 Tomcat,而是将 war 包部署到其他服务器的时候,内嵌服务器不会和外部服务器冲突. 即 java -jar 使用的是内嵌的 Tomcat 服务器,直接部署 war 到其他服务器的时候,不使用内嵌服务器 。

第二步 : 添加插件

apply plugin: 'war'

配置到此结束 , 我发现并不需要像其它博客所说重写 Application 相关方法 。

第三步 : 打包

gradle  build  

第四步 : 启动

java -jar web-0.0.1-SNAPSHOT.war  // 打包成功后 ,切换到 build/libs目录 , 你可以直接启动。

文件打包成功后默认路径在项目 build/libs 目录下。
我们发现同正常的 war 包相比 , 可执行 war 的 WEB-INF 目录下多了 lib-provided 文件夹.

在这里插入图片描述

里面存储了内嵌容器相关的 jar 包 :

在这里插入图片描述

同时在根目录下多了个 org 文件夹,如下图 :

在这里插入图片描述

org 文件夹下是可执行 war 的启动类 ,可执行 jar 包也有这些文件。如下图:

在这里插入图片描述


打正常 war 包 (不包含内嵌服务器)

在打可执行 war 的时候 , 我们添加了 war 插件 , apply plugin: ‘war’ , 这一步给 gradle 添加了 BootWar 任务 , 但是同时关闭了 war 任务 , 因此 build 的时候执行了以下任务 :

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :bootWar            // 注意, 添加了此任务
> Task :war SKIPPED   // 注意 , 此任务跳过了
> Task :assemble
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses

如果我们想打正常 war 包 。 除了上述可执行 war 的配置外, 我们还需要进行额外配置 。
第一步 : 在 build.gradle 中额外添加

war {
    enabled = true  // 开启 war 任务 
}

bootWar {
    classifier = 'boot'  //  修改 bootWar 的文件名称 , 这一步是为了区分可执行 war 与 正常 war
}

第二步 : 打包

gradle  build 

打包过程我们会发现 :

> Task :processResources
> Task :classes
> Task :bootWar
> Task :war    // 该任务没有被跳过
> Task :assemble
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses

打包完成后,我们来看 build/libs 目录下同时生成了两个 war 文件,如下图 :

在这里插入图片描述


分析

第一个 war 包大小为 29M , 该 war 包为正常 war 包 , 没有内嵌服务器 。
第二个 war 包大小为 37M , 同第一个包相比名字后多了- boot , 因为 build.gradle 中我们指定了 classifier = ‘boot’ ,同时第二个war 包是可执行 war 包 , 含有内嵌服务器 。
我们来打开第一个正常的 war 包 , 首先根目录少了一个启动类的文件夹 , 如下图 :

在这里插入图片描述

其次, WEB-INF 少了 lib-provided 文件夹 , 这也是为什么正常 war 更小的原因 。 如下图 :

在这里插入图片描述

因此如果你直接执行,会报错 , 因为没有内嵌容器,需要放到外置 Tomcat 中,报错如下 :
web-0.0.1-SNAPSHOT.war 中没有主清单属性

java -jar web-0.0.1-SNAPSHOT.war

而你执行 :

java -jar web-0.0.1-SNAPSHOT-boot.war  // 有内嵌容器, 启动了应用, 也可以部署到外置 Tomcat 中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值