摘要本文是一篇面向 Maven 熟练用户的 Gradle 多模块 Spring Boot 项目实战指南。文章基于 IntelliJ IDEA 2026.1、Gradle 8.14.5、Spring Boot 2.17.3 和 JDK 1.8 环境从零开始详细演示了如何创建 Gradle 多模块项目、配置远程仓库包括阿里云镜像、管理依赖版本、处理 Gradle 传递依赖的常见问题、优化子模块依赖配置并最终完成 Spring Boot 项目的两种打包方式Fat Jar 和依赖外置。文中提供了完整的配置文件示例旨在帮助读者快速掌握 Gradle 在复杂项目中的核心配置技巧。目录创建项目项目目录结构创建module远程仓库设置默认远程仓库配置阿里云远程仓库配置本地仓库配置gradle工作目录不建议使用本地maven仓库版本控制Gradle传递依赖的坑子模块通用引入依赖写法springboot项目打包依赖包打包启动包外部lib目录整体配置使用idea版本2026.1Gradle版本8.14.5springboot版本2.17.3jdk版本1.8。文章适合对gradle一窍不通但对maven很熟练的朋友学习。从创建项目到构建启动逐步讲解每一步gradle配置的含义都会说明。创建项目使用idea工具创建gradle项目。点击 New Project , 如果已经打开了idea点击菜单File 》New》projectname输入项目名称自定义Location项目路径。自定义Build system选择GradleGradle DSL选择gradle配置使用的DSL语言。DSL 其实是 Domain Specific Language 的缩写中文翻译为领域特定语言下简称 DSL而与 DSL 相对的就是 GPL是General Purpose Language 的简称即通用编程语言也就是我们非常熟悉的Java、Python 以及 C 语言等等。Gradle distributionWrapper是 Gradle 官方推荐的标准做法它通过项目内置的脚本gradlew或gradlew.bat来自动下载并使用指定的 Gradle 版本。这是团队开发推荐模式保证团队开发人员使用的版本统一。如果是内网项目没有外网则只能选择Local Installation本安装后配置。点击create后就会出现如下界面。开始时如果Gradle distribution选择的Wrapper可能会下载Gralde,并执行构建项目,此时gradle窗口还是空白,等待构建完成后,gradle窗口会显示内容。项目目录结构根路径下会有settings.gradle文件用来标记根项目和子模块之间的关系。只有根项目下才有这个配置文件。build.gradle 文件中编辑插件坐标配置项目依赖等。此文件根项目和子模块都有类似maven的pom文件。上图左边项目窗口其中.idea .gradle分别是idea和gradle的工作目录。build是gradle任务build的输出目录gradle有wrapper的相关配置src跟maven项目结构一样有java资源文件配置文件等。gradlew和gradelw.bat跟wrapper有关系bat是windows执行build.gradle和settings.gradle至关重要修改的就是这两个文件以下还会提到会着重描述。右侧是gradle窗口主要用到task下的build 用来打包和clean 类似maven的clean删除打包文件help里的projects 查看项目结构和properties gradle运行时会有的properties创建module在项目根目录上右键创建moduleName输入模块名称Location、Build System、JDK、Gralde DSL、Parent都是默认选择。使用gralde grovvy语言构建module的parent就是刚才创建的跟项目。GroupId每个模块要不一样只需要最后一个点之后的部分不一样即可可以跟module的名字一致。要求每个模块的group id不一样是因为此处有一个坑如果模块的group id一样只有artificat id不一样。自动创建java包就会一样。当创建一个类修改包位置时多个模块有相同的包路径改完包位置类所在的位置可能不是你要的位置。并且也利于区分每个类是属于哪个模块的。AtifactId一般就跟module的名字一样。点击create之后。看下图可以看到模块下只有一个build.gradle文件这是正常的。如果使用idea创建module时module下有settings.gradle文件这是idea的bug引起的一定要删除否则会出现Sync idea changges失败。根目录下的src可以删除。接着我会创建其他module。common模块主要是一些公共代码部门供其他模块引用。BillPage是静态页面个人项目需要将页面也做了内嵌没有做动静分离独立部署。BillStarter模块是spring boot项目启动模块启动类在这个模块中每个子模块创建之处都会生成一Main.java文件可以直接删除。此时查看settings.gradle文件内容因为根项目和所有模块均已确定此文件内容也不再发生变化所有内容都是new project和new module时自动生成的。远程仓库设置默认远程仓库项目结构创建好后在进行依赖包引入之前首先需要设置下远程仓库让gradle可以识别去何处下载依赖包。在build.gradle文件中repositories { mavenCentral() }加入以上配置后就能直接远程下载依赖包。gradle是没有远程仓库的需要使用maven的远程仓库。这么配置后下载地址默认https://repo.maven.apache.org/maven2/参见官方文档RepositoryHandler (Gradle API 9.6.1)配置阿里云远程仓库但这个地址下载的太慢了想使用aliyun的仓库下载jar包需要添加maven { url https://maven.aliyun.com/nexus/content/groups/public/ }配置本地仓库远程仓库下载依然是需要网络环境下载速度受网络影响可能还会慢此时就想让Gradle使用本maven仓库需要添加mavenLocal() 参见官方文档Repository Types上图解释了Gradle拥有和maven一样的识别逻辑如果在~/.m2/settings.xml中定义了仓库位置优先取这个文件中的位置其次是读取M2_HOME/conf下的settings.xml。否则默认仓库就认为是~/.m2/repository。因为根项目和所有的子模块都需要仓库配置就可以写到allprojects下allprojects { repositories { mavenLocal() maven { url https://maven.aliyun.com/nexus/content/groups/public/ } mavenCentral() } }网络搜索以及大模型搜索关于Gradle如何确定使用的maven本地仓库目录还有一种说法是在Gradle的工作目录下Gradle默认工作目录是~/.gradle也可以通过GRADLE_USER_HOME环境变量设置创建gradle.properties文件并配置systemProp.maven.repo.local D:\\soft\\repository 或 maven.repo.local D:/soft/repository尝试并不生效。配置gradle工作目录gradle下载的包是保存在gradle工作目录下的caches\modules-2\files-2.1默认情况在~/.gradle/caches/modules-2/files-2.1如果需要放到D盘可以配置环境变量GRADLE_USER_HOME因为都有jar包我就直接跟跟maven仓库配置到了同一个目录。win11系统配置环境变量步骤设置》系统》关于》高级系统设置》环境变量》新建系统变量。不建议使用本地maven仓库官方文档中并不建议使用maven本地仓库所谓的本地仓库并不是一个maven仓库而是maven的缓存可能出现信息不完整。信任和安全的风险Gradle并不信任本地仓库maven构件可能随时会变,本地仓库文件也会随时变,同时也会导致gradle构建更慢参考官方文档Repository Types只有以下场景不得不用maven本地仓库时采用项目A 和项目B使用的构建工具不一样需要相互依赖包此时可以使用本地仓库作为临时桥梁建议优先使用内部仓库也就是我们搭建的maven私服没有私服本地仓库最好只用于本地构建使用项目A的变更能否在项目B中生效类似1说的需要依赖时推荐才有复合的构建方式只有万不得已的情况下才是用本地仓库。综合考虑风险使用本地仓库是只有本地包且没有私服的情况下使用如下图使用includeGroup,只有这个group才会去本地仓库找包版本控制spring boot项目肯定会有依赖包的版本管理。下面我们开始修改配置文件build.gradle。版本依赖参考官方文档Dependency Management Plugin需要插件io.spring.dependency-management在plugins下声明。但根项目并不应用。因为是创建的springboot项目并且版本依赖需要引入bom还需要插件org.springframework.boot依然是声明不应用。plugins { id java id org.springframework.boot version 2.7.13 apply false id io.spring.dependency-management version 1.1.7 apply false }因为版本控制每个子模块都需要所以写到subprojects下subprojects { apply plugin: java apply plugin: io.spring.dependency-management dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } }在common模块下引入所有的包此时不用写包的版本号。dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 代码生成器 implementation com.baomidou:mybatis-plus-generator implementation org.freemarker:freemarker // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // jwt token implementation com.auth0:java-jwt // fastjson implementation com.alibaba:fastjson // 工具类 implementation org.apache.commons:commons-lang3 // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test }编译common模块点击build成功说明版本依赖已经生效不用再些版本号了。在其他模块下引入common模块dependencies { implementation project(:common) }在page模块引入对应驱动包这个模块多为静态文件所以不引入common模块。下面的引入也体现了包冲突的话排除的一种方式。dependencies { implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow implementation org.springframework.boot:spring-boot-starter-freemarker }在starter模块引入其他模块dependencies { implementation project(:common) implementation project (:schedule) implementation project (:login) implementation project (:notice) implementation project (:BillPage) implementation project (:log) implementation project (:permission) implementation project (:config) implementation project (:file) }此时开始启动starer模块的启动类发现config模块编译报错缺pagehelper的包检查config模块已经引入common模块common模块已经引入pagehelper的包且common模块引入包成功并不报错。Gradle传递依赖的坑上述报错的主要原因是虽然引入了common模块并且common模块也已经引入了相关包。但是config模块是引入不了common模块的包的。这是Gradle的机制。有两种方案可以解决将java插件改为java-library插件并将common模块implementation引入包的方式改为api方式。就能传递依赖。在其他模块也进行implementation引入一次本文采用第二种方式解决。dependencies { implementation project(:common) // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 代码生成器 implementation com.baomidou:mybatis-plus-generator implementation org.freemarker:freemarker // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // jwt token implementation com.auth0:java-jwt // fastjson implementation com.alibaba:fastjson // 工具类 implementation org.apache.commons:commons-lang3 // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test }所有引入common模块的模块都按照以上方式引入后启动成功。并且点击根项目的build也能编译成功。子模块通用引入依赖写法所有引入common模块的模块都按照以上方式引入后启动成功。并且点击根项目的build也能编译成功。但是发现重复引入动作太多这些重复的引入可以写到根项目的subprojects下子模块就不需要重复再写。subprojects { apply plugin: java apply plugin: io.spring.dependency-management dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // 工具类 implementation org.apache.commons:commons-lang3 } }每个子模块只需要引入特有的依赖包即可例如login模块引入token的jwt的包dependencies { implementation project(:common) // jwt token implementation com.auth0:java-jwt }notice模块需要引入email邮箱功能的包和json处理的包以及微信通知需要http请求的包dependencies { implementation project(:common) // fastjson implementation com.alibaba:fastjson // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // httpclient implementation org.apache.httpcomponents:httpclient }没有特有包的模块dependencies { implementation project(:common) }springboot项目打包虽然启动成功以及点击根项目的build也能成功打包不报错但查看build目录下的包并不是可执行的springboot包。我们引入springboot插件还没有模块apply这个插件启动模块就需要apply这个插件apply plugin:org.springframework.boot然后在点击根项目的build然后查看starter模块下build目录打包成功。依赖包打包启动包外部lib目录以上方式是springboot的打包方式将所有的依赖包都打到了可执行jar包内。一般情况下能满足业务需求。对于频繁需要更新的项目或者poc的项目多个项目模块共同组成一个功能所有的包加起来就会很大其中就包含重复的依赖jar包把依赖jar包打到可启动jar包同级的lib目录下会方便许多需要在starter模块添加配置// 配置 bootJar将依赖分离出来 bootJar { // 禁用默认的 fat jar 打包方式 enabled false archiveFileName.set(bill.jar) } // 启用普通的 jar 打包 jar { archiveFileName.set(bill.jar) enabled true exclude *.yml, *.yaml, logback-spring.xml manifest { attributes ( Main-Class: com.erbaoge.bill.ErbaogeApplication, Class-Path: configurations.runtimeClasspath.files.collect { lib/$it.name }.join( )) } } // 创建复制依赖的任务 tasks.register(copyDependencies, Copy) { from configurations.runtimeClasspath into build/libs/lib } tasks.register(copyConfig, Copy) { from src/main/resources include *.yml, *.yaml, logback-spring.xml into build/libs/config } // 让 build 任务依赖 copyDependencies和 copyConfig build.dependsOn copyDependencies, copyConfig以上配置将包里面的配置文件也进行了配置打包到同级的config目录下而jar包内没有配置文件。config相关配置不需要可以直接删除。点击根项目下的build后整体配置如果还是不太明白项目都干了什么或者添加内容到文件中的具体位置容易搞错下面将本项目中完整的配置文件附上。根项目下的settings.gradlerootProject.name SpringBootGradle include common include schedule include login include notice include BillPage include log include permission include config include file include BillStarter根项目下的build.gradleplugins { id java id org.springframework.boot version 2.7.13 apply false id io.spring.dependency-management version 1.1.7 apply false } allprojects { group com.erbaoge version 1.0-SNAPSHOT repositories { mavenLocal() maven { url https://maven.aliyun.com/nexus/content/groups/public/ } mavenCentral() } } subprojects { apply plugin: java apply plugin: io.spring.dependency-management sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 tasks.withType(JavaCompile) { options.encoding UTF-8 } dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // 工具类 implementation org.apache.commons:commons-lang3 } }一般子模块build.gradledependencies { implementation project(:common) }特殊子模块login的build.gradledependencies { implementation project(:common) // jwt token implementation com.auth0:java-jwt }特殊模块page的build.gradledependencies { implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow implementation org.springframework.boot:spring-boot-starter-freemarker }starter模块的build.gradleapply plugin:org.springframework.boot dependencies { implementation project(:common) implementation project (:schedule) implementation project (:login) implementation project (:notice) implementation project (:BillPage) implementation project (:log) implementation project (:permission) implementation project (:config) implementation project (:file) // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // fastjson implementation com.alibaba:fastjson // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter implementation net.sourceforge.tess4j:tess4j // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test } // 配置 bootJar将依赖分离出来 bootJar { // 禁用默认的 fat jar 打包方式 enabled false archiveFileName.set(bill.jar) } // 启用普通的 jar 打包 jar { archiveFileName.set(bill.jar) enabled true exclude *.yml, *.yaml, logback-spring.xml manifest { attributes ( Main-Class: com.erbaoge.bill.ErbaogeApplication, Class-Path: configurations.runtimeClasspath.files.collect { lib/$it.name }.join( )) } } // 创建复制依赖的任务 tasks.register(copyDependencies, Copy) { from configurations.runtimeClasspath into build/libs/lib } tasks.register(copyConfig, Copy) { from src/main/resources include *.yml, *.yaml, logback-spring.xml into build/libs/config } // 让 build 任务依赖 copyDependencies和 copyConfig build.dependsOn copyDependencies, copyConfig如有其他问题欢迎在评论去讨论
Gradle从入门到实战:Maven老手使用idea如何平滑迁移并构建多模块Spring Boot项目
发布时间:2026/7/9 11:25:19
摘要本文是一篇面向 Maven 熟练用户的 Gradle 多模块 Spring Boot 项目实战指南。文章基于 IntelliJ IDEA 2026.1、Gradle 8.14.5、Spring Boot 2.17.3 和 JDK 1.8 环境从零开始详细演示了如何创建 Gradle 多模块项目、配置远程仓库包括阿里云镜像、管理依赖版本、处理 Gradle 传递依赖的常见问题、优化子模块依赖配置并最终完成 Spring Boot 项目的两种打包方式Fat Jar 和依赖外置。文中提供了完整的配置文件示例旨在帮助读者快速掌握 Gradle 在复杂项目中的核心配置技巧。目录创建项目项目目录结构创建module远程仓库设置默认远程仓库配置阿里云远程仓库配置本地仓库配置gradle工作目录不建议使用本地maven仓库版本控制Gradle传递依赖的坑子模块通用引入依赖写法springboot项目打包依赖包打包启动包外部lib目录整体配置使用idea版本2026.1Gradle版本8.14.5springboot版本2.17.3jdk版本1.8。文章适合对gradle一窍不通但对maven很熟练的朋友学习。从创建项目到构建启动逐步讲解每一步gradle配置的含义都会说明。创建项目使用idea工具创建gradle项目。点击 New Project , 如果已经打开了idea点击菜单File 》New》projectname输入项目名称自定义Location项目路径。自定义Build system选择GradleGradle DSL选择gradle配置使用的DSL语言。DSL 其实是 Domain Specific Language 的缩写中文翻译为领域特定语言下简称 DSL而与 DSL 相对的就是 GPL是General Purpose Language 的简称即通用编程语言也就是我们非常熟悉的Java、Python 以及 C 语言等等。Gradle distributionWrapper是 Gradle 官方推荐的标准做法它通过项目内置的脚本gradlew或gradlew.bat来自动下载并使用指定的 Gradle 版本。这是团队开发推荐模式保证团队开发人员使用的版本统一。如果是内网项目没有外网则只能选择Local Installation本安装后配置。点击create后就会出现如下界面。开始时如果Gradle distribution选择的Wrapper可能会下载Gralde,并执行构建项目,此时gradle窗口还是空白,等待构建完成后,gradle窗口会显示内容。项目目录结构根路径下会有settings.gradle文件用来标记根项目和子模块之间的关系。只有根项目下才有这个配置文件。build.gradle 文件中编辑插件坐标配置项目依赖等。此文件根项目和子模块都有类似maven的pom文件。上图左边项目窗口其中.idea .gradle分别是idea和gradle的工作目录。build是gradle任务build的输出目录gradle有wrapper的相关配置src跟maven项目结构一样有java资源文件配置文件等。gradlew和gradelw.bat跟wrapper有关系bat是windows执行build.gradle和settings.gradle至关重要修改的就是这两个文件以下还会提到会着重描述。右侧是gradle窗口主要用到task下的build 用来打包和clean 类似maven的clean删除打包文件help里的projects 查看项目结构和properties gradle运行时会有的properties创建module在项目根目录上右键创建moduleName输入模块名称Location、Build System、JDK、Gralde DSL、Parent都是默认选择。使用gralde grovvy语言构建module的parent就是刚才创建的跟项目。GroupId每个模块要不一样只需要最后一个点之后的部分不一样即可可以跟module的名字一致。要求每个模块的group id不一样是因为此处有一个坑如果模块的group id一样只有artificat id不一样。自动创建java包就会一样。当创建一个类修改包位置时多个模块有相同的包路径改完包位置类所在的位置可能不是你要的位置。并且也利于区分每个类是属于哪个模块的。AtifactId一般就跟module的名字一样。点击create之后。看下图可以看到模块下只有一个build.gradle文件这是正常的。如果使用idea创建module时module下有settings.gradle文件这是idea的bug引起的一定要删除否则会出现Sync idea changges失败。根目录下的src可以删除。接着我会创建其他module。common模块主要是一些公共代码部门供其他模块引用。BillPage是静态页面个人项目需要将页面也做了内嵌没有做动静分离独立部署。BillStarter模块是spring boot项目启动模块启动类在这个模块中每个子模块创建之处都会生成一Main.java文件可以直接删除。此时查看settings.gradle文件内容因为根项目和所有模块均已确定此文件内容也不再发生变化所有内容都是new project和new module时自动生成的。远程仓库设置默认远程仓库项目结构创建好后在进行依赖包引入之前首先需要设置下远程仓库让gradle可以识别去何处下载依赖包。在build.gradle文件中repositories { mavenCentral() }加入以上配置后就能直接远程下载依赖包。gradle是没有远程仓库的需要使用maven的远程仓库。这么配置后下载地址默认https://repo.maven.apache.org/maven2/参见官方文档RepositoryHandler (Gradle API 9.6.1)配置阿里云远程仓库但这个地址下载的太慢了想使用aliyun的仓库下载jar包需要添加maven { url https://maven.aliyun.com/nexus/content/groups/public/ }配置本地仓库远程仓库下载依然是需要网络环境下载速度受网络影响可能还会慢此时就想让Gradle使用本maven仓库需要添加mavenLocal() 参见官方文档Repository Types上图解释了Gradle拥有和maven一样的识别逻辑如果在~/.m2/settings.xml中定义了仓库位置优先取这个文件中的位置其次是读取M2_HOME/conf下的settings.xml。否则默认仓库就认为是~/.m2/repository。因为根项目和所有的子模块都需要仓库配置就可以写到allprojects下allprojects { repositories { mavenLocal() maven { url https://maven.aliyun.com/nexus/content/groups/public/ } mavenCentral() } }网络搜索以及大模型搜索关于Gradle如何确定使用的maven本地仓库目录还有一种说法是在Gradle的工作目录下Gradle默认工作目录是~/.gradle也可以通过GRADLE_USER_HOME环境变量设置创建gradle.properties文件并配置systemProp.maven.repo.local D:\\soft\\repository 或 maven.repo.local D:/soft/repository尝试并不生效。配置gradle工作目录gradle下载的包是保存在gradle工作目录下的caches\modules-2\files-2.1默认情况在~/.gradle/caches/modules-2/files-2.1如果需要放到D盘可以配置环境变量GRADLE_USER_HOME因为都有jar包我就直接跟跟maven仓库配置到了同一个目录。win11系统配置环境变量步骤设置》系统》关于》高级系统设置》环境变量》新建系统变量。不建议使用本地maven仓库官方文档中并不建议使用maven本地仓库所谓的本地仓库并不是一个maven仓库而是maven的缓存可能出现信息不完整。信任和安全的风险Gradle并不信任本地仓库maven构件可能随时会变,本地仓库文件也会随时变,同时也会导致gradle构建更慢参考官方文档Repository Types只有以下场景不得不用maven本地仓库时采用项目A 和项目B使用的构建工具不一样需要相互依赖包此时可以使用本地仓库作为临时桥梁建议优先使用内部仓库也就是我们搭建的maven私服没有私服本地仓库最好只用于本地构建使用项目A的变更能否在项目B中生效类似1说的需要依赖时推荐才有复合的构建方式只有万不得已的情况下才是用本地仓库。综合考虑风险使用本地仓库是只有本地包且没有私服的情况下使用如下图使用includeGroup,只有这个group才会去本地仓库找包版本控制spring boot项目肯定会有依赖包的版本管理。下面我们开始修改配置文件build.gradle。版本依赖参考官方文档Dependency Management Plugin需要插件io.spring.dependency-management在plugins下声明。但根项目并不应用。因为是创建的springboot项目并且版本依赖需要引入bom还需要插件org.springframework.boot依然是声明不应用。plugins { id java id org.springframework.boot version 2.7.13 apply false id io.spring.dependency-management version 1.1.7 apply false }因为版本控制每个子模块都需要所以写到subprojects下subprojects { apply plugin: java apply plugin: io.spring.dependency-management dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } }在common模块下引入所有的包此时不用写包的版本号。dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 代码生成器 implementation com.baomidou:mybatis-plus-generator implementation org.freemarker:freemarker // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // jwt token implementation com.auth0:java-jwt // fastjson implementation com.alibaba:fastjson // 工具类 implementation org.apache.commons:commons-lang3 // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test }编译common模块点击build成功说明版本依赖已经生效不用再些版本号了。在其他模块下引入common模块dependencies { implementation project(:common) }在page模块引入对应驱动包这个模块多为静态文件所以不引入common模块。下面的引入也体现了包冲突的话排除的一种方式。dependencies { implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow implementation org.springframework.boot:spring-boot-starter-freemarker }在starter模块引入其他模块dependencies { implementation project(:common) implementation project (:schedule) implementation project (:login) implementation project (:notice) implementation project (:BillPage) implementation project (:log) implementation project (:permission) implementation project (:config) implementation project (:file) }此时开始启动starer模块的启动类发现config模块编译报错缺pagehelper的包检查config模块已经引入common模块common模块已经引入pagehelper的包且common模块引入包成功并不报错。Gradle传递依赖的坑上述报错的主要原因是虽然引入了common模块并且common模块也已经引入了相关包。但是config模块是引入不了common模块的包的。这是Gradle的机制。有两种方案可以解决将java插件改为java-library插件并将common模块implementation引入包的方式改为api方式。就能传递依赖。在其他模块也进行implementation引入一次本文采用第二种方式解决。dependencies { implementation project(:common) // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 代码生成器 implementation com.baomidou:mybatis-plus-generator implementation org.freemarker:freemarker // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // jwt token implementation com.auth0:java-jwt // fastjson implementation com.alibaba:fastjson // 工具类 implementation org.apache.commons:commons-lang3 // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test }所有引入common模块的模块都按照以上方式引入后启动成功。并且点击根项目的build也能编译成功。子模块通用引入依赖写法所有引入common模块的模块都按照以上方式引入后启动成功。并且点击根项目的build也能编译成功。但是发现重复引入动作太多这些重复的引入可以写到根项目的subprojects下子模块就不需要重复再写。subprojects { apply plugin: java apply plugin: io.spring.dependency-management dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // 工具类 implementation org.apache.commons:commons-lang3 } }每个子模块只需要引入特有的依赖包即可例如login模块引入token的jwt的包dependencies { implementation project(:common) // jwt token implementation com.auth0:java-jwt }notice模块需要引入email邮箱功能的包和json处理的包以及微信通知需要http请求的包dependencies { implementation project(:common) // fastjson implementation com.alibaba:fastjson // 邮件 implementation org.springframework.boot:spring-boot-starter-mail // httpclient implementation org.apache.httpcomponents:httpclient }没有特有包的模块dependencies { implementation project(:common) }springboot项目打包虽然启动成功以及点击根项目的build也能成功打包不报错但查看build目录下的包并不是可执行的springboot包。我们引入springboot插件还没有模块apply这个插件启动模块就需要apply这个插件apply plugin:org.springframework.boot然后在点击根项目的build然后查看starter模块下build目录打包成功。依赖包打包启动包外部lib目录以上方式是springboot的打包方式将所有的依赖包都打到了可执行jar包内。一般情况下能满足业务需求。对于频繁需要更新的项目或者poc的项目多个项目模块共同组成一个功能所有的包加起来就会很大其中就包含重复的依赖jar包把依赖jar包打到可启动jar包同级的lib目录下会方便许多需要在starter模块添加配置// 配置 bootJar将依赖分离出来 bootJar { // 禁用默认的 fat jar 打包方式 enabled false archiveFileName.set(bill.jar) } // 启用普通的 jar 打包 jar { archiveFileName.set(bill.jar) enabled true exclude *.yml, *.yaml, logback-spring.xml manifest { attributes ( Main-Class: com.erbaoge.bill.ErbaogeApplication, Class-Path: configurations.runtimeClasspath.files.collect { lib/$it.name }.join( )) } } // 创建复制依赖的任务 tasks.register(copyDependencies, Copy) { from configurations.runtimeClasspath into build/libs/lib } tasks.register(copyConfig, Copy) { from src/main/resources include *.yml, *.yaml, logback-spring.xml into build/libs/config } // 让 build 任务依赖 copyDependencies和 copyConfig build.dependsOn copyDependencies, copyConfig以上配置将包里面的配置文件也进行了配置打包到同级的config目录下而jar包内没有配置文件。config相关配置不需要可以直接删除。点击根项目下的build后整体配置如果还是不太明白项目都干了什么或者添加内容到文件中的具体位置容易搞错下面将本项目中完整的配置文件附上。根项目下的settings.gradlerootProject.name SpringBootGradle include common include schedule include login include notice include BillPage include log include permission include config include file include BillStarter根项目下的build.gradleplugins { id java id org.springframework.boot version 2.7.13 apply false id io.spring.dependency-management version 1.1.7 apply false } allprojects { group com.erbaoge version 1.0-SNAPSHOT repositories { mavenLocal() maven { url https://maven.aliyun.com/nexus/content/groups/public/ } mavenCentral() } } subprojects { apply plugin: java apply plugin: io.spring.dependency-management sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 tasks.withType(JavaCompile) { options.encoding UTF-8 } dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } // 统一管理所有依赖版本 dependencies { dependency com.baomidou:mybatis-plus-boot-starter:3.5.12 dependency com.baomidou:mybatis-plus-generator:3.5.12 dependency com.alibaba:druid-spring-boot-starter:1.2.8 dependency com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1 dependency com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.0 dependency com.alibaba:fastjson:1.2.83 dependency dom4j:dom4j:1.6.1 dependency com.google.zxing:core:3.3.0 dependency com.alibaba:easyexcel:3.3.4 dependency com.jcraft:jsch:0.1.54 dependency io.springfox:springfox-swagger2:3.0.0 dependency com.github.xiaoymin:knife4j-spring-ui:3.0.3 dependency com.auth0:java-jwt:3.10.3 dependency net.sourceforge.tess4j:tess4j:5.8.0 } } dependencies { // web 排除内置tomcat改用undertow implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow // 参数校验 implementation org.springframework.boot:spring-boot-starter-validation // mybatis-plus implementation com.baomidou:mybatis-plus-boot-starter // 分页插件 implementation com.github.pagehelper:pagehelper-spring-boot-starter: // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // swagger knife4j implementation io.springfox:springfox-swagger2 implementation com.github.xiaoymin:knife4j-spring-ui // 工具类 implementation org.apache.commons:commons-lang3 } }一般子模块build.gradledependencies { implementation project(:common) }特殊子模块login的build.gradledependencies { implementation project(:common) // jwt token implementation com.auth0:java-jwt }特殊模块page的build.gradledependencies { implementation(org.springframework.boot:spring-boot-starter-web) { exclude group: org.springframework.boot, module: spring-boot-starter-tomcat } implementation org.springframework.boot:spring-boot-starter-undertow implementation org.springframework.boot:spring-boot-starter-freemarker }starter模块的build.gradleapply plugin:org.springframework.boot dependencies { implementation project(:common) implementation project (:schedule) implementation project (:login) implementation project (:notice) implementation project (:BillPage) implementation project (:log) implementation project (:permission) implementation project (:config) implementation project (:file) // 阿里druid连接池 implementation com.alibaba:druid-spring-boot-starter // mysql驱动 runtime范围 runtimeOnly com.mysql:mysql-connector-j // easyexcel excel导入导出 implementation com.alibaba:easyexcel // 二维码条形码 implementation com.google.zxing:core // sftp implementation com.jcraft:jsch // httpclient implementation org.apache.httpcomponents:httpclient // xml dom4j implementation dom4j:dom4j // fastjson implementation com.alibaba:fastjson // lombok compileOnly org.projectlombok:lombok annotationProcessor org.projectlombok:lombok // 配置加密 jasypt implementation com.github.ulisesbocchio:jasypt-spring-boot-starter implementation net.sourceforge.tess4j:tess4j // 测试依赖 testImplementation junit:junit testImplementation org.springframework.boot:spring-boot-starter-test } // 配置 bootJar将依赖分离出来 bootJar { // 禁用默认的 fat jar 打包方式 enabled false archiveFileName.set(bill.jar) } // 启用普通的 jar 打包 jar { archiveFileName.set(bill.jar) enabled true exclude *.yml, *.yaml, logback-spring.xml manifest { attributes ( Main-Class: com.erbaoge.bill.ErbaogeApplication, Class-Path: configurations.runtimeClasspath.files.collect { lib/$it.name }.join( )) } } // 创建复制依赖的任务 tasks.register(copyDependencies, Copy) { from configurations.runtimeClasspath into build/libs/lib } tasks.register(copyConfig, Copy) { from src/main/resources include *.yml, *.yaml, logback-spring.xml into build/libs/config } // 让 build 任务依赖 copyDependencies和 copyConfig build.dependsOn copyDependencies, copyConfig如有其他问题欢迎在评论去讨论