美文网首页springboot demo实战项目
springboot gradle构建 demo实战项目

springboot gradle构建 demo实战项目

作者: 灰色调诺言 | 来源:发表于2019-06-19 14:20 被阅读30次

    简介

    Gradle 这是一个基于 JVM 的富有突破性构建工具。Gradle 正迅速成为许多开源项目和前沿企业构建系统的选择,同时也在挑战遗留的自动化构建项目。本demo主要讲述如何用gradle构建一个微服务项目。

    阅读本demo之前需要对Gradle有入门的了解,Gradle入门

    Git地址

    https://gitee.com/wqrzsy/lp-demo/tree/master/lp-springboot-gradle

    更多demo请关注

    springboot demo实战项目
    java 脑洞

    项目分析

    1. 项目结构


      image.png

    项目从根项目(lp-springboot-gradle)开始包含一个组项目(lp-cms-group)

    然后组项目下包含3个子项目(lp-dialog, lp-proto, lp-service-one)

    image.png

    然后我们留意到每个项目底下都会有一个build.gradle的文件,这个就是项目的gradle构建文件

    1. 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插件,使用了这插件在声明依赖的时候可以忽略掉版本号

    1. 接下来说一下组项目的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
            }
        }
    
    
    }
    
    
    
    1. 子项目的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(' ')
        }
    
    }
    
    
    
    1. settings.gradle是定义父子项目关系的gradle文件


      image.png
    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'
    
    
    

    项目扩展

    1. protobuf项目的gradle配置, lp-proto

    2. 启动含图形界面的task的gradle配置,lp-dialog


      image.png
    3. springboot 瘦身的gradle配置, lp-service-one

    demo项目导入

    参考: https://www.jianshu.com/p/cd0275a2f5fb

    如果这篇文章对你有帮助请给个star


    image.png

    相关文章

      网友评论

        本文标题:springboot gradle构建 demo实战项目

        本文链接:https://www.haomeiwen.com/subject/qvifqctx.html