简介
gradle是后端开发常用的构建工具,本文用实例介绍如何使用maven打包SpringBoot项目。
SpringBoot打包实例
代码
以Gradle创建SpringBoot项目。
项目结构
build.gradle
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
settings.gradle
rootProject.name = 'test_springboot_gradle'
gradle命令
启动函数
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("[DemoApplication.main]: 10");
SpringApplication.run(DemoApplication.class, args);
}
}
测试
点击Tasks=> build=> bootjar或者Tasks=> build=> build
点击bootjar:生成jar,路径:项目路径/build/libs(如下图所示)
点击build
其生成的可运行jar是一模一样的。只不过build多生成了reports和test-results目录。
执行java -jar test_springboot_gradle-0.0.1-SNAPSHOT.jar
[DemoApplication.main]: 10
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
2020-08-21 16:02:08.132 INFO 61424 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on DESKTOP-LOU6VCO with PID 61424 (E:\work\Idea_proj\demo\test_springboot_gradle\build\libs\test_springboot_gradle-0.0.1-SNAPSHOT.jar started by 27165 in E:\work\Idea_proj\demo\test_springboot_gradle\build\libs)
2020-08-2......
点击Tasks=> build=> jar
先Tasks=> build=> clean,后Tasks=> build=> jar。发现虽然生成build文件夹,但没有jar包
控制台输出
23:43:54: Executing task 'jar'...
> Task :compileJava
> Task :processResources
> Task :classes
> Task :jar SKIPPED
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
23:43:56: Task execution finished 'jar'.
发现jar被跳过了。解决方法:在build.gradle中添加这个
jar{
enabled = true
}
此时会生成jar文件。
执行java -jar test_springboot_gradle-0.0.1-SNAPSHOT.jar
test_springboot_gradle-0.0.1-SNAPSHOT.jar中没有主清单属性
SpringBoot打包详解
bootjar对比jar
bootjar命令生成的test_springboot_gradle-0.0.1-SNAPSHOT.jar结构
jar命令生成的test_springboot_gradle-0.0.1-SNAPSHOT.jar结构
bootjar与jar的区别
bootjar生成的包可以直接使用java -jar xxx.jar运行,但jar生成的包不能运行,只能被引用。
bootjar与jar的来源
这两个命令是'org.springframework.boot'插件的,引入此插件即可。Idea用gradle生成的springboot项目的build.gradle的插件如下:
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
gradle命令如下:
若去掉此插件:
plugins {
// id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
则如下图所示
常用操作
修改bootjar命令生成的包名与版本
bootjar{
baseName = 'my' //最终生成my.jar
//archiveName = 'my.jar' //这样写也可以
version = '0.0.1'
}
手写gradle打包任务
其他网址
Gradle 自定义Task 打Jar包 - Java天堂Gradle 历险记(四):正确的打包jar的方式 – LeadroyaL's website
法1:修改 task jar来生成fatjar
存在风险。有时会有依赖覆盖或者某个文件没拷贝的情况。不推荐
task makeJar(type: Jar) {
delete 'build/mylib/test.jar'
baseName = 'test' //最终生成test.jar
//archiveName = 'test.jar' //这样写也可以
from('build/classes/java') //需要打jar的目录
from('XXX') //需包含的其他目录
exclude('dir1/', 'file1') //不打包指定的文件夹/文件
//exclude {
// it.name.startsWith('R$');
//}
//destinationDir = file('build/mylib') //生成的jar存放的位置
}
makeJar.dependsOn(build)
最后执行gradlew makeJar即可。
法2:copy任务
task makeJar(type: Copy) {
delete 'build/libs/test.jar'
from( 'build/intermediates/bundles/release ')
into( 'build/libs')
include('classes.jar')
rename('classes.jar', 'test.jar')
}
makeJar.dependsOn(build)
法3:shadow 插件生成 fatjar
maven的 maven-shade-plugin 的 gradle 版本。
apply plugin: 'com.github.johnrengelman.shadow'
sourceCompatibility = 1.8
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.3"
}
}
shadowJar {
baseName = 'hello'
classifier = null
version = null
zip64 true
manifest {
attributes 'Main-Class': 'com.example.Main'
}
}
使用方法 :gradle shadowJar ,在 build/libs 里生成文件。
手动打包实例
build.gradle示例
apply plugin: 'java'
apply plugin: 'idea'
version = '1.0'
repositories {
mavenCentral()
}
project.ext {
springVersion = '4.0.4.RELEASE'
minaVersion = '2.0.13'
}
dependencies {
compile('com.alibaba:dubbo:2.4.9') {
exclude group: 'org.springframework', module: 'spring'
}
compile( "org.apache.zookeeper:zookeeper:3.3.6") {
exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
}
compile( "com.github.sgroschupf:zkclient:0.1") {
exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
}
compile "org.springframework:spring-webmvc:$springVersion",
"org.springframework:spring-web:$springVersion",
...
"net.sf.json-lib:json-lib:2.2.1:jdk15",
fileTree(dir: 'lib', include: '*.jar')
}
jar {
String someString = ''
configurations.runtime.each {someString = someString + " lib\\"+it.name}
manifest {
attributes 'Main-Class': 'com.each.dubboMainEnd'
attributes 'Class-Path': someString
}
}
//清除上次的编译过的文件
task clearPj(type:Delete){
delete 'build','target'
}
task copyJar(type:Copy){
from configurations.runtime
into ('build/libs/lib')
}
//把JAR复制到目标目录
task release(type: Copy,dependsOn: [build,copyJar]) {
// from 'conf'
// into ('build/libs/eachend/conf') // 目标位置
}
说明
apply plugin: 'idea' 用于把项目构建成idea项目
apply plugin: 'java' 用于添加Java插件,以及一些内置任务,打包jar就要用到这里的插件。
jar{...} 添加项目所需要的依赖包
首先这定义了一个someString用来存放依赖包的信息,通过configurations.runtime拿到所有的运行时的依赖jar包,然后.each遍历他,通过it.name获取到每个的jar包的name,赋值。
manifest即是编译完成后生成jar包中的MANIFEST.MF配置信息
task copyJar(type:Copy){...} 建立函数copyJar 用于把依赖的jar复制到对应的目录下。
release(...){...} 打包的时候的执行的函数
dependsOn[build,copyJar]这里会让执行relese函数的时候先执行build(系统自带的函数) 和copyJar
最后通过gradle release命令进行打包