简介
Gradle 这是一个基于 JVM 的富有突破性构建工具。Gradle 正迅速成为许多开源项目和前沿企业构建系统的选择,同时也在挑战遗留的自动化构建项目。本demo主要讲述如何用gradle构建一个微服务项目。
阅读本demo之前需要对Gradle有入门的了解,Gradle入门
Git地址
https://gitee.com/wqrzsy/lp-demo/tree/master/lp-springboot-gradle
更多demo请关注
springboot demo实战项目
java 脑洞
java 面试宝典
开源工具
项目分析
- 项目结构
项目从根项目(lp-springboot-gradle)开始包含一个组项目(lp-cms-group)
然后组项目下包含3个子项目(lp-dialog, lp-proto, lp-service-one)
然后我们留意到每个项目底下都会有一个build.gradle的文件,这个就是项目的gradle构建文件
- rootProject
首先我们从根节点开始, lp-springboot-gradle的build.gradle文件
apply from: "config.gradle"
group = 'wqr'
version = '0.0.1-SNAPSHOT'
//allprojects里是项目本身需要的依赖,比如项目依赖springboot,就是在这里配置的
allprojects {
//如果要让Gradle自动生成Intellij的项目文件
apply plugin: "idea"
// 定义maven仓库
repositories {
mavenLocal()
maven {
// 这里mavenURL 是配置在config.gradle中
url mavenURL
}
mavenCentral()
}
//添加 utf-8 的支持,避免中文注释生成 Javadoc 文件出现编码错误
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
// 自定义task任务,遍历子项目,打印子项目信息
tasks.create('printProjectInfo') {
doLast {
task ->
println "project name is $task.project.name, version = $task.project.version, group = $task.project.group "
}
}
}
def noJavaProjectNames = [
'lp-cms-group'
]
// subProjects 和 allProjects 一样,只是subProjects 定义的是子项目,配置在本项目不会生效,
// allProject 是子项目和本项目都会生效
subprojects {
//buildscript里是gradle脚本执行所需依赖,分别是对应的maven库和插件
buildscript {
// 定义gradle 依赖的仓库
repositories {
mavenLocal()
maven { url mavenURL }
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
//gradle 依赖的插件
dependencies {
// springboot 插件
classpath "org.springframework.boot:spring-boot-gradle-plugin:${vers.springBoot}"
// gradle 工具插件
classpath "gradle.plugin.com.github.viswaramamoorthy:gradle-util-plugins:0.1.0-RELEASE"
//缩短命令行长度
classpath "gradle.plugin.ua.eshepelyuk:ManifestClasspath:1.0.0"
}
}
// 排除组项目,因为组项目不是标准java项目
if (!noJavaProjectNames.contains(project.name)) {
apply plugin: "java" // 使用java插件构建标准java工程
apply plugin: "maven" // 使用maven 仓库
apply plugin: 'groovy'//使用 groovy 插件构建项目
//设置jdk的版本
sourceCompatibility = vers.jdk
targetCompatibility = vers.jdk
}
}
// idea的配置
idea {
module {
// 是否下载源码
downloadSources = true
}
project {
jdkName = vers.jdk
languageLevel = vers.jdk
}
}
这里讲述下
apply from: "config.gradle"
apply from 表示引入文件,这里就是引入一个"config.gradle"的文件
config.gradle 是一份自定义全局配置文件,定义全局属性
ext {
mavenURL = 'http://maven.aliyun.com/nexus/content/groups/public/'
/**
* 全局版本
*/
vers = [
project : '1.0',
jdk : '11',
springBoot : '2.1.5.RELEASE',
springCloud : 'Greenwich.SR1',
jwt : '3.8.1',
swagger2 : '2.9.2',
grpc : '1.20.0',
protobuf : '3.6.1',
grpcStarter : '2.4.0.RELEASE',
commonsLang3: '3.9',
commonsCodec: '1.11',
commonsPool2: '2.6.1',
redisson : '3.10.6',
]
/**
* 全局依赖
*/
allDependsMap = [
// spring
'spring-boot-starter-web' : "org.springframework.boot:spring-boot-starter-web",
'spring-retry' : "org.springframework.retry:spring-retry",
'spring-boot-configuration-processor' : "org.springframework.boot:spring-boot-configuration-processor",
'spring-boot-starter-actuator' : "org.springframework.boot:spring-boot-starter-actuator",
'spring-boot-starter-data-jpa' : "org.springframework.boot:spring-boot-starter-data-jpa",
'spring-cloud-starter-openfeign' : "org.springframework.cloud:spring-cloud-starter-openfeign",
'spring-cloud-starter-config' : "org.springframework.cloud:spring-cloud-starter-config",
'spring-cloud-starter-netflix-eureka-client': "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client",
'spring-cloud-starter-netflix-ribbon' : "org.springframework.cloud:spring-cloud-starter-netflix-ribbon",
'spring-cloud-starter-zipkin' : "org.springframework.cloud:spring-cloud-starter-zipkin",
'spring-boot-starter-data-redis' : "org.springframework.boot:spring-boot-starter-data-redis",
'spring-boot-starter-test' : "org.springframework.boot:spring-boot-starter-test",
'spring-boot-starter-security' : "org.springframework.boot:spring-boot-starter-security",
'spring-cloud-config-server' : "org.springframework.cloud:spring-cloud-config-server",
'spring-cloud-starter-netflix-eureka-server': "org.springframework.cloud:spring-cloud-starter-netflix-eureka-server",
'spring-cloud-starter-gateway' : "org.springframework.cloud:spring-cloud-starter-gateway",
// 杂
'spring-boot-admin-starter-server' : "de.codecentric:spring-boot-admin-starter-server:2.1.5",
'springfox-swagger2' : "io.springfox:springfox-swagger2:${vers.swagger2}",
'springfox-swagger-ui' : "io.springfox:springfox-swagger-ui:${vers.swagger2}",
'mysql-connector-java' : "mysql:mysql-connector-java",
'redisson' : "org.redisson:redisson:${vers.redisson}",
'kryo-shaded' : "com.esotericsoftware:kryo-shaded:4.0.2",
'grpc-spring-boot-starter' : "net.devh:grpc-spring-boot-starter:${vers.grpcStarter}",
'brave-instrumentation-grpc' : "io.zipkin.brave:brave-instrumentation-grpc:5.6.3",
// 工具
'guava' : "com.google.guava:guava:27.0.1-jre",
'commons-lang3' : "org.apache.commons:commons-lang3:${vers.commonsLang3}",
'commons-codec' : "commons-codec:commons-codec:${vers.commonsCodec}",
'commons-pool2' : "org.apache.commons:commons-pool2:${vers.commonsPool2}",
'java-jwt' : "com.auth0:java-jwt:${vers.jwt}",
'freemarker' : "org.freemarker:freemarker:2.3.23",
// javax
'jaxb-api' : "javax.xml.bind:jaxb-api:2.3.1",
'javax.annotation-api' : "javax.annotation:javax.annotation-api:1.2",
'activation' : "javax.activation:activation:1.1.1",
'validation-api' : "javax.validation:validation-api:2.0.1.Final",
'jsr311-api' : "javax.ws.rs:jsr311-api:1.1.1",
'jaxb-impl' : "com.sun.xml.bind:jaxb-impl:2.3.2",
'jaxb-core' : "com.sun.xml.bind:jaxb-core:2.3.0.1",
'grpc-protobuf' : "io.grpc:grpc-protobuf:${vers.grpc}",
'grpc-stub' : "io.grpc:grpc-stub:${vers.grpc}",
'grpc-netty-shaded' : "io.grpc:grpc-netty-shaded:${vers.grpc}",
]
/**
* springboot组依赖
*/
bootDepends = [
allDependsMap.'spring-boot-starter-web',
allDependsMap.'spring-retry',
allDependsMap.'spring-boot-configuration-processor',
allDependsMap.'spring-boot-starter-actuator',
allDependsMap.'springfox-swagger2',
allDependsMap.'springfox-swagger-ui',
]
/**
* common组依赖
*/
commonDepends = [
allDependsMap.'validation-api',
allDependsMap.'jsr311-api',
allDependsMap.'validation-api',
allDependsMap.'guava',
allDependsMap.'commons-lang3',
allDependsMap.'commons-codec',
allDependsMap.'java-jwt',
]
/**
* springboot-test组依赖
*/
bootTestDepends = [
allDependsMap.'spring-boot-starter-test',
]
}
这里我们看到全局依赖中的版本号是${vers.grpc},这种表示引用配置属性,这个属性的值在vers 中定义了,
然后我们也看到类似org.springframework.boot:spring-boot-starter-web这种是没配版本号,这因为我们引入了io.spring.dependency-management插件,使用了这插件在声明依赖的时候可以忽略掉版本号
- 接下来说一下组项目的grade文件
首先说一下组是什么,组是管理子项目的父级项目,所以组项目本身不是标准java项目,主要用于定义子项目的统一参数
group 'wqr'
version '0.0.1-SNAPSHOT'
// 定义非springboot 项目
def noBootJavaProjectNames = [
'lp-proto',
'lp-dialog'
]
subprojects {
// project.name 获取子项目名字
// project.group 获取子项目group
String name = project.name
//使用这个插件可以让减少项目的改动。而且,会检测其他插件的使用或者更新。比如,当应用了java插件,会自动在构建时打包成可执行的jar。
apply plugin: 'org.springframework.boot'
//允许你在声明依赖的时候忽略掉版本号,使用这项功能,只需要正常的声明依赖,不用写版本号就可以了
apply plugin: 'io.spring.dependency-management'
// 定义子项目依赖
dependencies {
// 定义在config.gradle中
compile bootDepends
testImplementation bootTestDepends
}
// 引入spring-cloud 依赖
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${vers.springCloud}"
}
}
// 排除不是springboot项目
if (noBootJavaProjectNames.contains(project.name)) {
// 取消springboot 打包过程
bootJar {
// springboot 打包过程, 需要Main函数
enabled = false
}
// 执行阶段
jar {
// 普通jar包,不需要main函数
// 是否禁止阶段
enabled = true
}
} else {
bootJar {
// springboot 打包过程, 需要Main函数
enabled = true
}
// 执行阶段
jar {
// 普通jar包,不需要main函数
// 是否禁止阶段
enabled = false
}
}
}
- 子项目的gradle文件
最后就是具体业务的微服gradle文件,该文件构建只需考虑业务项目所需的配置和依赖,比如在lp-service-one中做的jar包瘦身配置
group 'wqr'
version '0.0.1-SNAPSHOT'
// 定义项目依赖
dependencies {
// 定义在config.gradle中
compile allDependsMap.'mysql-connector-java'
}
// 清除现有的lib目录
task clearJar(type: Delete) {
delete "$buildDir\\libs\\lib"
}
// 将依赖包复制到lib目录
task copyJar(type: Copy, dependsOn: 'clearJar') {
// 复制文件
from configurations.compileClasspath
// 若文件夹不存在会自己创建
into "$buildDir\\libs\\lib"
}
// springboot打包过程
bootJar {
// 排除所有的jar
excludes = ["*.jar"]
// 执行lib目录的清除和复制任务
dependsOn clearJar
dependsOn copyJar
// 指定依赖包的路径
manifest {
attributes "Manifest-Version": 1.0,
'Class-Path': configurations.compileClasspath.files.collect { "lib/$it.name" }.join(' ')
}
}
- settings.gradle是定义父子项目关系的gradle文件
rootProject.name = 'lp-springboot-gradle'
include ':lp-cms-group'
include ':lp-cms-group:lp-service-one'
include ':lp-cms-group:lp-proto'
include ':lp-cms-group:lp-dialog'
项目扩展
-
protobuf项目的gradle配置, lp-proto
-
启动含图形界面的task的gradle配置,lp-dialog
-
springboot 瘦身的gradle配置, lp-service-one
demo项目导入
参考: https://www.jianshu.com/p/cd0275a2f5fb
公众号
五分钟了解前沿技术,大数据,微服务,区域链,提供java前沿技术干货,独立游戏制作技术分享
如果这篇文章对你有帮助请给个star