第一章 企业级 gradle 依赖管理层次结构设计

第一章 企业级 gradle 依赖管理层次结构设计

Gradle概述

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML。Gradle就是工程的管理,帮我们做了依赖、打包、部署、发布、各种渠道的差异管理等工作。

Gradle优势

  1. 一款最新的,功能最强大的构建工具,用它逼格更高
  2. 使用程序代替传统的XML配置,项目构建更灵活
  3. 丰富的第三方插件,让你随心所欲使用
  4. Maven、Ant能做的,Gradle都能做,但是Gradle能做的,Maven、Ant不一定能做。

Maven中依赖概述

  • 一方库:本工程中各个模块之间的依赖
  • 二方库(xxx-dependencies):企业内部的依赖库,一般指企业内部的其他项目发布的依赖(jar 包)
  • 三方库(xxx-parent):企业之外的第三方依赖库, 如 Spring、Apache、Google 等发布的依赖(jar 包)


一般来说,企业的开发框架搭建完成后,三方库依赖除了漏洞和 Bug 升级外,很少频繁升级大改,而企业内部的二方库由于迭代和更新,版本升级频率较三方库要高,所以层次结构中二方库依赖三方库三方库在更底层。先控制三方库依赖版本,在此基础上再控制二方库的版本。这里只对项目结构设计进行讲解,至于Nexus 私服搭建大家百度一下就好了。

项目搭建

本文项目地址 jingwei-cloud

新建项目初始化工程

**sparrow **模块为 **jingwei-cloud **的两方库模块,**jingwei-cloud **所有子模块均会引入该模块,这个模块相当于企业中的共享模块,后期也可以单独拆分成一个独立工程维护。

  • sparrow目录结构
    ![1-sparrow目录结构.jpeg](https://img-blog.csdnimg.cn/img_convert/161baf6e214ffe56eff25a0698ce3273.png#align=left&display=inline&height=736&margin=[object Object]&name=1-sparrow目录结构.jpeg&originHeight=736&originWidth=1366&size=123191&status=done&style=none&width=1366

jingwei-cloud配置

  • jingwei-cloud > build.gradle
buildscript {
    ext {
        set("springBootVersion", "2.3.4.RELEASE")
        set("dependencyManagementVersion", "1.0.10.RELEASE")
    }
}
description = "根目录用于管理所有项目"
configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/public/' }
        mavenCentral()
    }
    tasks.withType(JavaCompile) {
        options.encoding = "UTF-8"
    }
}

sparrow根模块

  • jingwei-cloud > sparrow > build.gradle
import org.springframework.boot.gradle.plugin.SpringBootPlugin

buildscript {
    ext {
        set("ignoreProjects",
            [
                project(":sparrow:sparrow-parent"),
                project(":sparrow:sparrow-dependencies"),
            ]
        )
        set("moduleProjects", subprojects - ignoreProjects)
        // 两方包 不能包含引用jar
        set("excludeProjects", project(":sparrow:sparrow-client"))
    }
}

plugins {
    id 'org.springframework.boot' version "$springBootVersion" apply false
    id 'io.spring.dependency-management' version "$dependencyManagementVersion" apply false
    id 'java'
}
description = "sparrow(麻雀), 基础工程,通用工程骨架"
allprojects {
    group = 'com.vastmoon.sparrow'
    version = '2.0.0-SNAPSHOT'
}

configure(moduleProjects) {
    apply plugin: "java"
    apply from: "${rootDir}/gradle/framework-module.gradle"
    sourceCompatibility = '1.8'
    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }
    test {
        useJUnitPlatform()
    }
}

configure(moduleProjects - excludeProjects) {
    apply plugin: "io.spring.dependency-management"
    dependencyManagement {
        imports {
            mavenBom SpringBootPlugin.BOM_COORDINATES
        }
        generatedPomCustomization {
            enabled = false
        }
    }

    dependencies {
        implementation(enforcedPlatform(project(":sparrow:sparrow-parent")))
        annotationProcessor 'org.projectlombok:lombok'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
        testImplementation('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
        }
        implementation("org.springframework.boot:spring-boot-starter-validation")
        implementation("org.apache.commons:commons-collections4")
        implementation("cn.hutool:hutool-all")
        implementation("org.apache.commons:commons-lang3")
        implementation("com.google.guava:guava")
    }
}


set("excludeProjects", project(":sparrow:sparrow-client")) client不能包含任何依赖,这个包可能会发给Dubbo等RPC框架实现远程调用,因此不能依赖第三方jar包

apply plugin: "io.spring.dependency-management"
    dependencyManagement {
        imports {
            mavenBom SpringBootPlugin.BOM_COORDINATES
        }
        generatedPomCustomization {
            enabled = false
        }
    }

这里有一个坑,如果不这样配置,会找不到spingboot的依赖,目前没有找到什么原因造成的。具体错误原因如下图:![1-gradle报错.jpeg](https://img-blog.csdnimg.cn/img_convert/75b4fb8898e1ce6a07858aec66c3b785.png#align=left&display=inline&height=736&margin=[object Object]&name=1-gradle报错.jpeg&originHeight=736&originWidth=1366&size=228996&status=done&style=none&width=1366)

sparrow-parent 配置

  • jingwei-cloud > sparrow > sparrow-parent > build.gradle
import org.springframework.boot.gradle.plugin.SpringBootPlugin

apply plugin: 'java-platform'
apply from: "$rootDir/gradle/publications.gradle"
ext {
    set('springCloudAlibabaVersion', "2.2.2.RELEASE")
    set('springCloudVersion', "Hoxton.SR8")
    set("collections4Version", "4.4")
    set("hutoolVersion", "5.4.7")
    set("ulisesbocchioVersion", "3.0.3")
    set("springSecurityJwtVersion", "1.1.1.RELEASE")
}
javaPlatform {
    allowDependencies()
}

dependencies {
    api enforcedPlatform(SpringBootPlugin.BOM_COORDINATES)
    api enforcedPlatform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
    api enforcedPlatform("com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}")
    constraints {
        api("org.apache.commons:commons-collections4:$collections4Version")
        api("cn.hutool:hutool-all:$hutoolVersion")
        api("com.github.ulisesbocchio:jasypt-spring-boot:$ulisesbocchioVersion")
        api('org.springframework.security:spring-security-jwt:$springSecurityJwtVersion')
    }

}

publishing {
    publications {
        //noinspection GroovyAssignabilityCheck
        mavenJava(MavenPublication) {
            //noinspection GroovyAssignabilityCheck
            from components.javaPlatform
        }
    }
}

sparrow-parent 模块为三方库管理模块,主要用于维护三方库, 这里用到的插件 java-platform 具体的配置信息大家可以去官网查看,官网地址 :https://docs.gradle.org/current/userguide/java_platform_plugin.html

sparrow-dependencies配置

  • jingwei-cloud > sparrow > sparrow-dependencies > build.gradle
apply plugin: 'java-platform'
apply from: "$rootDir/gradle/publications.gradle"
javaPlatform {
    allowDependencies()
}
dependencies {
    api enforcedPlatform(project(":sparrow:sparrow-parent"))
    constraints {
        parent.moduleProjects.sort { it.name }.each {
            api it
        }
    }
}

publishing {
    publications {
        //noinspection GroovyAssignabilityCheck
        mavenJava(MavenPublication) {
            //noinspection GroovyAssignabilityCheck
            from components.javaPlatform
        }
    }
}

sparrow-dependencies 模块为两方库模块,下面的配置为把两方模块加入到pom文件中

constraints {
        parent.moduleProjects.sort { it.name }.each {
            api it
        }
    }

项目编译

![1-sparrow-pom运行.jpeg](https://img-blog.csdnimg.cn/img_convert/73d274900918eedc04481ba17e3c04b0.png#align=left&display=inline&height=736&margin=[object Object]&name=1-sparrow-pom运行.jpeg&originHeight=736&originWidth=1366&size=140748&status=done&style=none&width=1366]

sparrow-parent pom文件

  • sparrow > sparrow-parent > build > publications > mavenJava > pom-default.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.vastmoon.sparrow</groupId>
  <artifactId>sparrow-parent</artifactId>
  <version>2.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.4</version>
      </dependency>
      <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.4.7</version>
      </dependency>
      <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot</artifactId>
        <version>3.0.3</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-jwt</artifactId>
        <version>$springSecurityJwtVersion</version>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.3.4.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR8</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>2.2.2.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

sparrow-dependencies pom文件

  • sparrow > sparrow-dependencies > build > publications > mavenJava > pom-default.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.vastmoon.sparrow</groupId>
  <artifactId>sparrow-dependencies</artifactId>
  <version>2.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.vastmoon.sparrow</groupId>
        <artifactId>sparrow-client</artifactId>
        <version>2.0.0-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>com.vastmoon.sparrow</groupId>
        <artifactId>sparrow-core</artifactId>
        <version>2.0.0-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>com.vastmoon.sparrow</groupId>
        <artifactId>sparrow-parent</artifactId>
        <version>2.0.0-SNAPSHOT</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

上传私服公共配置

这里参照了spring-framework的公共配置

  • gradle > framework-module.gradle
apply from: "$rootDir/gradle/publications.gradle"
jar {
	manifest.attributes["Implementation-Title"] = project.name
	manifest.attributes["Implementation-Version"] = project.version
	manifest.attributes["Automatic-Module-Name"] = project.name.replace('-', '.')  // for Jigsaw
	manifest.attributes["Created-By"] =
			"${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})"

//	from("${rootDir}/src/docs/dist") {
//		include "license.txt"
//		include "notice.txt"
//		into "META-INF"
//		expand(copyright: new Date().format("yyyy"), version: project.version)
//	}
}

publishing {
	publications {
		mavenJava(MavenPublication) {
			from components.java
//			artifact sourcesJar
//			artifact javadocJar
		}
	}
}

  • gradle > publications.gradle
apply plugin: "maven-publish"
publishing {
	publications {
		mavenJava(MavenPublication) {
			pom {
				afterEvaluate {
					name = project.description
					description = project.description
				}
			}
			versionMapping {
				usage('java-api') {
					fromResolutionResult()
				}
				usage('java-runtime') {
					fromResolutionResult()
				}
			}
		}
	}

	repositories {
		maven {
			// change to point to your repo, e.g. http://my.org/repo
			def releasesRepoUrl = "http://localhost:8081/repository/maven-releases/"
			def snapshotsRepoUrl = "http://localhost:8081/repository/maven-snapshots/"
			url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
			credentials {
				username = 'admin'
				password = 'admin123'
			}
		}
	}
}

可选模块

这里还创建了一个sparrow-gradle-plugin模块用于公司内部统一使用springboot版本

sparrow-gradle-plugin build.gradle

  • sparrow > sparrow-gradle-plugin > build.gradle
plugins {
    id "java-gradle-plugin"
}
apply from: "$rootDir/gradle/publications.gradle"
dependencies {
    implementation "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
    implementation "io.spring.gradle:dependency-management-plugin:$dependencyManagementVersion"
}
gradlePlugin {
    plugins {
        sparrowGradlePlugin {
            //noinspection GroovyAssignabilityCheck
            id = 'com.vastmoon.sparrow'
            //noinspection GroovyAssignabilityCheck
            implementationClass = 'com.vastmoon.sparrow.gradle.SparrowGradlePlugin'
        }
    }
}

sparrow-gradle-plugin 插件类

public class SparrowGradlePlugin implements Plugin<Project> {
    public static final String BOM_COORDINATES = "com.vastmoon.sparrow:sparrow-dependencies:";
    @Override
    public void apply(Project project) {
        project.getPlugins().apply(SpringBootPlugin.class);
    }
}

引用sparrow到其他工程中

新建一个新项目 sparrow-example

  • sparrow-example > settings.gradle
pluginManagement {
    repositories {
        gradlePluginPortal()
        maven { url 'https://maven.aliyun.com/repository/public/' }
        mavenCentral()
        mavenLocal()
        maven { url 'http://localhost:8081/repository/maven-public/' }
    }
}
rootProject.name = 'sparrow-example'


  • sparrow-example > build.gradle
buildscript {
    ext {
        set("sparrowVersion", "2.0.0-SNAPSHOT")
    }
}
plugins {
    id 'com.vastmoon.sparrow' version "$sparrowVersion" apply false
    id 'java'
}

description = "sparrow测试项目"
group = 'com.vastmoon.example'
version = '0.0.1-SNAPSHOT'
repositories {
    mavenLocal()
    maven { url 'https://maven.aliyun.com/repository/public/' }
    mavenCentral()
    maven { url 'http://localhost:8081/repository/maven-public/' }
}
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
test {
    useJUnitPlatform()
}
apply plugin: "io.spring.dependency-management"
dependencyManagement {
    imports {
        mavenBom "com.vastmoon.sparrow:sparrow-dependencies:$sparrowVersion"
    }
}
apply plugin: "org.springframework.boot"
dependencies {
    implementation("com.vastmoon.sparrow:sparrow-core")
    annotationProcessor 'org.projectlombok:lombok'
    compileOnly 'org.projectlombok:lombok'
    implementation("org.springframework.boot:spring-boot-starter-web")
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }

}

总结

这样的结构我参照着springboot源码和spring-framework源码的工程目录总结出来的,现在看来和maven的项目管理没什么区别了,希望gradle构建多模块项目越来越方便。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值