gradle多模块依赖管理最佳实践

news/2024/5/20 4:12:31 标签: java, gradle, maven

gradle多模块依赖管理最佳实践

  • 多模块项目依赖管理
    • 定义子模块
    • 使用buildSrc定义插件
      • SofastModulePlugin
      • Optional 依赖
    • 增加dependencies子模块
    • 其他子模块
      • web

多模块项目依赖管理

依赖管理是项目开发过程中必不可少的操作,在gradle如何优雅的管理多个模块依赖是一个非常值得探讨的问题,本文总结了最佳管理的方式,如 统一三方依赖版本,dependencies

定义子模块

rootProject.name = 'project'
include("dependencies")
include("common") 
include("web") 
include("domain") 
include("service") 

使用buildSrc定义插件

gradle">plugins {
    id 'java-gradle-plugin'
    id "java"
    id "groovy"
}

description = "sofast dependency manager"
group 'cc.sofast.dependency'
version '1.0.0'

repositories {
    mavenLocal()
    mavenCentral()
    gradlePluginPortal()
    maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'https://repo.spring.io/milestone' }
}

dependencies {
    implementation('org.springframework.boot:org.springframework.boot.gradle.plugin:3.1.5')
    implementation('io.spring.gradle:dependency-management-plugin:1.1.3')
}

gradlePlugin {
    plugins {
        version {
            id = 'sofast.module.plugin'
            implementationClass = 'cc.sofastframework.gradle.SofastModulePlugin'
            displayName = "Dependency Manager Plugin"
            description = "Manage Dependent Versions"
        }
    }
}

SofastModulePlugin

java">public class SofastModulePlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        System.out.println("Sofast Dependency Manager plugin.");

        //java 插件
        project.getPlugins().apply(JavaPlugin.class);
        project.getPlugins().apply(JavaBasePlugin.class);

        //springboot
        Object springBootPluginEnable = project.getProperties().get("springBootPluginEnabled");
        if (Boolean.valueOf(String.valueOf(springBootPluginEnable)).equals(Boolean.TRUE)) {
            System.out.println("enabled SpringBootPlugin and DependencyManagementPlugin.");
            project.getPlugins().apply(SpringBootPlugin.class);
            project.getPlugins().apply(DependencyManagementPlugin.class);
        }

        project.getPlugins().apply(JavaConventionsPlugin.class);

        //依赖仓库
        project.getRepositories().mavenLocal();
        project.getRepositories().mavenCentral();
        project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl("https://maven.aliyun.com/nexus/content/groups/public/"));
        project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl("https://repo.spring.io/milestone"));
    }
}
  • JavaConventionsPlugin 引入optional 依赖
java">package cc.sofastframework.gradle;

import cc.sofastframework.gradle.optional.OptionalDependenciesPlugin;
import org.gradle.api.JavaVersion;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.api.tasks.javadoc.Javadoc;
import org.gradle.external.javadoc.CoreJavadocOptions;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;


/**
 * @author apple
 */
public class JavaConventionsPlugin implements Plugin<Project> {

    private static final String SOURCE_AND_TARGET_COMPATIBILITY = "17";

    private static final String ENCODING = "UTF-8";

    @Override
    public void apply(Project project) {
        System.out.println("JavaConventionsPlugin is enabled");
        //enabled optional plugin
        project.getPlugins().apply(OptionalDependenciesPlugin.class);
        //configuration convention
        project.getPlugins().withType(JavaBasePlugin.class, (java) -> {
            configureJavaConventions(project);
            configureJavadocConventions(project);
            configureDependencyManagement(project);
        });
    }

    private void configureJavadocConventions(Project project) {
        project.getTasks().withType(Javadoc.class, (javadoc) -> {
            CoreJavadocOptions options = (CoreJavadocOptions) javadoc.getOptions();
            options.source(SOURCE_AND_TARGET_COMPATIBILITY);
            options.encoding(ENCODING);
            options.addStringOption("Xdoclint:none", "-quiet");
        });
    }

    private void configureJavaConventions(Project project) {
        if (!project.hasProperty("toolchainVersion")) {
            JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
            javaPluginExtension.setSourceCompatibility(JavaVersion.toVersion(SOURCE_AND_TARGET_COMPATIBILITY));
        }
        project.getTasks().withType(JavaCompile.class, (compile) -> {
            compile.getOptions().setEncoding(ENCODING);
            List<String> args = compile.getOptions().getCompilerArgs();
            if (!args.contains("-parameters")) {
                args.add("-parameters");
            }
            if (project.hasProperty("toolchainVersion")) {
                compile.setSourceCompatibility(SOURCE_AND_TARGET_COMPATIBILITY);
                compile.setTargetCompatibility(SOURCE_AND_TARGET_COMPATIBILITY);
            } else if (buildingWithJava17(project)) {
                args.addAll(Arrays.asList("-Werror", "-Xlint:unchecked", "-Xlint:deprecation", "-Xlint:rawtypes",
                        "-Xlint:varargs"));
            }
        });
    }

    private boolean buildingWithJava17(Project project) {
        return !project.hasProperty("toolchainVersion") && JavaVersion.current() == JavaVersion.VERSION_17;
    }

    private void configureDependencyManagement(Project project) {
        ConfigurationContainer configurations = project.getConfigurations();
        Configuration dependencyManagement = configurations.create("dependencyManagement", (configuration) -> {
            configuration.setVisible(false);
            configuration.setCanBeConsumed(false);
            configuration.setCanBeResolved(false);
        });
        configurations
                .matching((c) -> c.getName().endsWith("Classpath") || c.getName().toLowerCase().endsWith("annotationprocessor"))
                .all((c) -> c.extendsFrom(dependencyManagement));
        Dependency pulsarDependencies = project.getDependencies().enforcedPlatform(project.getDependencies()
                .project(Collections.singletonMap("path", ":dependencies")));
        dependencyManagement.getDependencies().add(pulsarDependencies);
        project.getPlugins().withType(OptionalDependenciesPlugin.class, (optionalDependencies) -> configurations
                .getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME).extendsFrom(dependencyManagement));
    }
}

Optional 依赖

java">public class OptionalDependenciesPlugin implements Plugin<Project> {

	/**
	 * Name of the {@code optional} configuration.
	 */
	public static final String OPTIONAL_CONFIGURATION_NAME = "optional";

	@Override
	public void apply(Project project) {
		Configuration optional = project.getConfigurations().create("optional");
		optional.setCanBeConsumed(false);
		optional.setCanBeResolved(false);
		project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
			SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class)
					.getSourceSets();
			sourceSets.all((sourceSet) -> {
				project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName())
						.extendsFrom(optional);
				project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName())
						.extendsFrom(optional);
			});
		});
	}

}

增加dependencies子模块

dependencies 模块统一管理三方包的版本和dependencies 依赖如下:

gradle">import static org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES

plugins {
    id 'java-platform'
}

javaPlatform {
    allowDependencies()
}

ext {
    seataVersion = '1.6.1'
    feignVersion = '12.1'
    mybatisPlusVersion = '3.5.3.1'
}

dependencies {
    constraints {
        api "io.seata:seata-rm-datasource:$seataVersion"
        api "io.github.openfeign:feign-core:$feignVersion"
        api "com.baomidou:mybatis-plus-boot-starter:$mybatisPlusVersion"
    }
    println("spring boot version: " + BOM_COORDINATES)
    api platform(BOM_COORDINATES)
    api platform('org.springframework.cloud:spring-cloud-dependencies:2022.0.4')
}

其他子模块

web

gradle">//引入插件
plugins {
    id 'sofast.module.plugin'
}

//引入依赖,会自动引入dependencies 继承其定义的版本
dependencies {
    implementation(project(":domain"))
    optional 'org.springframework.boot:spring-boot-starter-jdbc'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
}

http://www.niftyadmin.cn/n/5133673.html

相关文章

【Java】选择语句、循环语句

选择语句 if if 语句的括号内必须是布尔表达式&#xff1b; else if 语句的括号内也必须是布尔表达式&#xff1b; public static void main(String[] args) {// 根据年龄输出int age 0;Scanner scanner new Scanner(System.in);age scanner.nextInt();// 括号里面必须是布…

一个基于Excel模板快速生成Excel文档的小工具

介绍 DocumentGenerator是一个Excel快速生成工具&#xff0c;目标以后还能实现Word、pdf等的文件的生成。该程序独立运行&#xff0c;可通过HTTP接口调用其生成接口。 典型使用场景为如下&#xff1a; 使用者编写模板文件使用者准备模板文件的填充JSON数据内容使用者通过网络…

beyond compare 4密钥2023大全,beyond compare 4注册码最新

beyond compare 4是一款文件对比软件&#xff0c;可以快速比较文件和文件夹、合并以及同步&#xff0c;非常实用&#xff0c;一些用户想知道beyond compare 4密钥有哪些&#xff0c;本文为大家带来了介绍哦~ 密钥&#xff1a; w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwf…

CSS3中的字体和文本样式

CSS3优化了CSS 2.1的字体和文本属性&#xff0c;同时新增了各种文字特效&#xff0c;使网页文字更具表现力和感染力&#xff0c;丰富了网页设计效果&#xff0c;如自定义字体类型、更多的色彩模式、文本阴影、生态生成内容、各种特殊值、函数等。 1、字体样式 字体样式包括类…

【Shell 系列教程】shell变量(二)

文章目录 往期回顾前言使用变量只读变量删除变量变量类型Shell 字符串单引号双引号双引号的优点&#xff1a; 拼接字符串使用双引号拼接Shell 数组定义数组读取数组获取数组的长度 Shell 注释多行注释 往期回顾 【Shell 系列教程】shell介绍&#xff08;一&#xff09; 前言 …

Jenkins git 克隆代码超时问题解决

目录 一、问题描述二、解决方案方式一&#xff1a;手动配置超时时间方式二&#xff1a;浅克隆&#xff08;推荐&#xff09; 一、问题描述 在使用 Jenkins 首次进行服务部署的时候&#xff0c;如果我们项目的 .git 文件夹太大&#xff0c;可能会导致 git clone 失败。 在 Jen…

LeetCode题:88合并两个有序数组,283移动零,448找到所有数组中消失的数字

目录 88合并两个有序数组 1、题目要求 2、解题思路 &#xff08;1&#xff09;、暴力解法&#xff1a; &#xff08;2&#xff09;、双指针&#xff0c;使用第三数组的解法&#xff1a; 3、代码展示 &#xff08;1&#xff09;、暴力解法&#xff1a; &#xff08;2&am…

车载网络通信

文章目录 车载网络通信未来车载网络架构的发展趋势 车载网络通信 车载网络架构&#xff08;In-Vehicle Network Architecture&#xff09;是指车辆内部各种电子控制单元&#xff08;ECU&#xff09;之间的通信和连接系统。随着汽车行业的发展&#xff0c;车载网络架构已经从简…