使用gradle创建多模块spring boot应用程序-新的心得

818 阅读4分钟

0-新的心得

编辑历史

2023-12-08 10:22 , 记录自己在创建多模块spring boot应用程序时的关于gradle的一些问题

宜需求评审 生发不易,且码且珍惜

前置工具

Gitee: 
IDEA: IntelliJ IDEA 2021.2.1 (Ultimate Edition)
Spring Boot: 3.2.0
JDK: liberica-17 BellSoft Liberica JDK version 17.0.9

1-初始化项目

1.1-在Gitee中新建仓库

项目名称: 2023-12-08-lucky-coffee

在Gitee中新建仓库:gitee.com/projects/ne…

仓库名称: 2023-12-08-lucky-coffee

路径: (与仓库名称相同)

生成的仓库地址:gitee.com/yourname/20…

选择开源:所有人可见

初始化仓库: 1、选择语言 - java 2、添加 .gitignore 模板 - java 3、添加开源许可证 - Apache2.0

设置模板: 1、Readme文件 2、Issue模板文件 3、Pull Request模板文件

选择分支模型:单分支模型(只创建master分支)

1.2-本地创建项目

在本地(Windows主机)新建名为 2023-12-08-lucky-coffee 的文件夹,进入到此文件夹中,使用 git init 命令 初始化仓库

$ git init

对于身处内网中的机器可以设置代理访问远程仓库

git config --local http.proxy http://username:password@ip:port
git config --local https.proxy https://username:password@ip:port

对于密码中的特殊字符需要转义, eg: # --> %23

使用 git remote add origin https://gitee.com/yourname/2023-12-08-lucky-coffee.git 命令添加远程仓库

使用 git pull origin master 命令拉取远程仓库变更

查看仓库状态

$ git status
On branch master
nothing to commit, working tree clean

2-使用IDEA新建spring boot project

使用IDEA(IntelliJ IDEA 2021.2.1) - 新建项目。使用 Spring Initalizr 创建名为 lucky-coffee 的 Spring Boot应用程序

Snipaste_2023-12-08_10-07-24.png

The [Groovy DSL] is the accepted languages for Gradle scripts。

lucky-coffee 目录结构分析, 进入到 lucky-coffee 文件夹

2.1-settings.gradle 文件

The settings.gradle is typically found in the root directory of the project. There is only one root project per build.

rootProject.name = 'lucky-coffee'

Define the project name: The settings file defines your project name。

Add subprojects: The settings file defines the structure of the project by including subprojects。eg:

rootProject.name = 'lucky-coffee'
include("app")
include("library")

2.2-build.gradle 文件

The build script is either a build.gradle file written in Groovy

build.gradle 文件内容

2023-12-08 13:25,初始化时我添加了很多项目编译依赖,不用扣细节,这部分我还会修改

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', "2023.0.0")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

plugins 解析

build.gradle build script 中,有如下插件

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

Plugins extend Gradle’s functionality and can contribute tasks to a project. Adding a plugin to a build is called applying a plugin and makes additional functionality available.

The application plugin facilitates creating an executable JVM application. The only mandatory configuration for the plugin is the specification of the main class (i.e. entry point) of the application.

参见:docs.gradle.org/current/use…

The Spring Boot Gradle Plugin (id 'org.springframework.boot' version '3.2.0') provides Spring Boot support in [Gradle]

参见:plugins.gradle.org/plugin/org.…

Applied in isolation the Spring Boot Gradle Plugin makes few changes to a project. Instead, the plugin detects when certain other plugins are applied and reacts accordingly. For example, when the java plugin is applied a task for building an executable jar is automatically configured.

To manage dependencies in your Spring Boot application, you can either apply the [io.spring.dependency-management] plugin

When you apply the io.spring.dependency-management plugin, Spring Boot’s plugin will automatically import the spring-boot-dependencies bom from the version of Spring Boot that you are using.

configurations 解析

Configures the dependency configurations for this project.

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

这里的配置是对下文即将导入的 lombok 依赖进行配置

dependencies 解析

Configures the dependencies for this project.

repositories 解析

Configures the repositories for this project.

repositories {
    mavenCentral()
}

3-修改根目录下的 build.gradle 文件

3.1-相关 buildscripts-blocks

参考:www.baeldung.com/gradle-buil…

`allProjects` block configures the root project and each of the sub-projects.

`subProjects` block, unlike allProjects, only configures the sub-projects.

`plugins` extend the capability of Gradle by bringing a useful set of features. For example, the `java` plugin adds tasks like assemble, build, clean, jar, documentation, etc., and much more.

`dependencies` by its name imply that it’s a place to declare all jars required by our project.

`repositories` block contains the location from where Gradle will download jars declared in the dependencies block. One can declare multiple locations that execute in the declaration order.

3.2-修改后的build.gradle 文件

在下面的文件中使用了allprojects {}subprojects {} 使所有子项目都可以共享配置。这样可以避免在每个子项目中重复配置相同的依赖项,也可以统一管理插件的使用和配置,提高项目的整体一致性和可维护性,提高项目的开发效率。

参见:docs.gradle.org/current/dsl…

// buildscript{}块:用于指定构建脚本所需的仓库;配置构建脚本自身所需的类路径和依赖项。gradle插件依赖声明通常包括在dependencies{}块中。位于构建脚本的顶层。
buildscript {
    ext {
        set('springVersion', "1.1.4")
        set('springBootVersion', "3.2.0")
        set('springCloudVersion', "2023.0.0")
    }

    // 构建脚本所需的仓库
    repositories {
        mavenCentral()
    }
    // Gradle plugin dependencies
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("io.spring.gradle:dependency-management-plugin:${springVersion}")
    }
}

// 应用和管理项目所需的gradle插件,可以简化插件的引入和应用过程,不需要手动声明依赖项。
plugins {
    id 'java-library'
//    2023-12-08 14:19,为什么会将下面的两行代码注释,是因为如果在这里启用gradle插件,会对 lucky-coffee 项目生效
//    出现 application - bootRun Task ,然后 build task 会报错 : Main class name has not been configured and it could not be resolved from classpath
//    原因:Spring Boot Gradle Plugin 与 java` plugin 同时使用: a task for building an executable jar is automatically configured
//    id 'org.springframework.boot' version '3.2.0'
//    id 'io.spring.dependency-management' version '1.1.4'
}

// `allProjects` block configures the root project and each of the sub-projects.
allprojects {

    // Configures the repositories for this project. 项目仓库
    repositories {
        mavenCentral()
    }

    group = 'com.example.luckycoffee'
    version = '0.0.1-SNAPSHOT'

    java {
        sourceCompatibility = '17'
    }

    tasks.named('test') {
        useJUnitPlatform()
    }
}

// `subProjects` block, unlike allProjects, only configures the sub-projects.
subprojects {
    // 应用一个通用的插件到所有子项目中; java plugin内置的可设变量
    apply plugin: 'java-library'
    // 应用插件
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }
    dependencies {
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }

    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
}

3.3-buildscript{}

Configures the build script classpath for this project.

buildscript{} 主要用于配置构建脚本本身所需的依赖项和资源。

具体来说,它的作用包括以下几个方面:

1、声明构建脚本的类路径依赖项:通过buildscript{}块可以指定Gradle构建脚本自身所需的类路径,例如插件依赖、第三方库等。这些依赖项会被用于构建过程中,而不是项目本身的编译和运行时依赖。

2、设置仓库:可以在buildscript{}块中指定构建脚本所需的仓库,以便 Gradle 能够下载所需的依赖项。

buildscript{}块指定了构建脚本所需的类路径依赖。

mavenCentral()指定了使用构建脚本所需的 Maven Central 仓库

classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")指定了使用的 Gradle 插件依赖。插件依赖声明通常包括在dependencies{}块中。

buildscript {
    ext {
        set('springVersion', "1.1.4")
        set('springBootVersion', "3.2.0")
        set('springCloudVersion', "2023.0.0")
    }
    repositories {
        mavenCentral()
    }
    // Gradle plugin dependencies
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("io.spring.gradle:dependency-management-plugin:${springVersion}")
    }
}

3.4-buildscript{}块 与 plugins{} 块

buildscript{}块和plugins{}块都用于管理gradle插件的依赖和应用,但是buildscript{}块更多地用于管理构建脚本自身所需的插件依赖,而plugins{}块用于应用和管理项目所需的插件。

两者可以同时存在于同一个构建脚本中,并且可以相互配合使用。例如,在buildscript{}块中声明构建脚本所需的第三方插件依赖,而在plugins{}块中声明项目所需的官方插件。

buildscript{}块: 1、用于配置构建脚本自身所需的类路径和依赖项。 2、通常用于声明构建脚本自身所需的插件依赖,比如构建脚本中用到的第三方插件。 3、插件依赖声明通常包括在dependencies{}块中。 4、位于构建脚本的顶层,即在构建脚本的根节点下。

buildscript {
    repositories {
        mavenCentral()
    }
    // Gradle plugin dependencies
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:3.2.0")
        classpath("io.spring.gradle:dependency-management-plugin:1.1.4")
    }
}

plugins{}块: 1、用于应用 Gradle 官方支持的插件或自定义插件。 2、可以简化插件的引入和应用过程,不需要手动声明依赖项。 3、通常用于声明应用的插件和版本。 4、位于构建脚本的顶层,即在构建脚本的根节点下。

plugins {
    id 'java-library'
}

3.5-Gradle插件依赖 与 项目依赖 是不同的

build.gradle文件中buildscript{}块中的dependencies{}块 主要是用于:Configures the build script classpath for this project. 我理解是Gradle插件依赖

build.gradle文件中的dependencies{}块主要是用于:Configures the dependencies for this project.

4-根目录下的 src 目录

首先需要删除 lucky-coffee 根目录下的 src 目录。由于这是多个微服务模块组成的项目。

5-新建 service-discovery 微服务模块

2023-12-08 15:00,下一步动作

6-遇到的错误信息

bootJar错误:Main class name has not been configured, and it could not be resolved from classpath

原因:Spring Boot Gradle Plugin 与 java` plugin 同时使用会导致a task for building an executable jar is automatically configured。

所以对于多模块的微服务项目,根目录下的 src 目录 已经被删除了,自然没有Main class,所以需要对根目录的build.gradle文件中不要对项目同时使用Spring Boot Gradle Plugin 与 java` plugin。

可以使用 legacy plugin application,只在 subprojects {} 中应用插件。