简介
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打包任务
法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命令进行打包
请先
!