gradle多模块依赖管理最佳实践
gradle多模块依赖管理最佳实践
- 多模块项目依赖管理
- 定义子模块
- 使用buildSrc定义插件
- SofastModulePlugin
- Optional 依赖
- 增加dependencies子模块
- 其他子模块
- web
多模块项目依赖管理
依赖管理是项目开发过程中必不可少的操作,在gradle如何优雅的管理多个模块依赖是一个非常值得探讨的问题,本文总结了最佳管理的方式,如 统一三方依赖版本,dependencies
定义子模块
rootProject.name = 'project'
include("dependencies")
include("common")
include("web")
include("domain")
include("service")
使用buildSrc定义插件
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
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
依赖
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 依赖
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 依赖如下:
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
//引入插件
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'
}