SpringBoot+maven聚合项目创建与打包部署的完整流程
1、旧工程改造
1.1 sc-common 中 pom.xml 改造:
1 删掉 pom.xml 中的父模块,把 sc-common 做为父模块
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <!– lookup parent from repository –> <relativePath/> </parent>
2 删掉 pom.xml 中的打包插件
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
3 新增打包插件
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin>
$ 为 1.8
4 完整的 build 内容
<!--打 jar 包--> <build> <plugins> <!-- maven聚合项目父工程必须要引用的插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin><!--跳过 test,因为 nacos yaml 文件中的的中文打包 test 会报错--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build>
5 完整的 pom.xml 内容
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的。 这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 --> <modelVersion>4.0.0</modelVersion> <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。--> <groupId>com.dt.cloud</groupId> <!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID。 在某个特定的group ID下,artifact ID也必须是唯一的。--> <artifactId>sc-common</artifactId> <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 --> <version>0.0.1-SNAPSHOT</version> <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 --> <packaging>pom</packaging><!--项目的名称, Maven产生的文档用 --> <name>sc-common</name> <!-- 项目的详细描述--> <description>点通软件的基础模块</description> <!-- 需要引入的子模块 --> <modules> <!-- 启动模块(必须) --> <module>sc-start</module> <!-- 初始化模块(必须) --> <module>sc-initialize</module> <!-- 密码校验模块 --> <module>password-check</module> <!-- 登录认证模块 --> <module>sc-auth</module> <!-- 点通有数模块 --> <module>sc-data-presented</module> </modules> <!--项目开发者属性,目前用来做版本声明 --> <properties> <!--点通 sc-common 版本 --> <dt.version>0.0.1-SNAPSHOT</dt.version> <!-- springboot 版本 --> <spring-boot.version>2.5.3</spring-boot.version> <!-- springcloud 版本 --> <spring-cloud.version>2020.0.3</spring-cloud.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <!-- jdk 版本 --> <java.version>1.8</java.version> <!-- 阿里巴巴 fastjson 版本 --> <fastjson.version>1.2.75</fastjson.version> <!-- swagger 相关 版本 --> <springfox-swagger2.version>2.6.1</springfox-swagger2.version> <springfox-swagger-ui.version>2.6.1</springfox-swagger-ui.version> <springfox-swagger3.version>3.0.0</springfox-swagger3.version> <swagger3.version>2.0.0.RELEASE</swagger3.version> <!-- knife4j 版本 --> <knife4j.version>3.0.2</knife4j.version> <!-- 数据库连接池 版本 --> <druid.version>1.1.22</druid.version> <!-- 数据库 版本 --> <mysql.version>8.0.20</mysql.version> <!-- mybatis-plus相关 版本 --> <mybatis-plus.version>3.3.2</mybatis-plus.version> <mybatis-plus-extension.version>3.4.0</mybatis-plus-extension.version> <!-- junit 单元测试 版本 --> <junit-test.version>4.12</junit-test.version> <!-- lombok 版本 --> <lombok.version>1.18.2</lombok.version> <!-- nacos 版本 --> <nacos.version>2.1.2.RELEASE</nacos.version> <!-- freemarker 版本 --> <freemarker.version>2.3.30</freemarker.version> </properties> <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。--> <dependencyManagement> <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。--> <dependencies> <!-- SpringBoot的依赖配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- SpringCloud 微服务 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${nacos.version}</version> </dependency> <!-- 配置中心支持 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${nacos.version}</version> </dependency> <!-- mybatis-plus 增强CRUD --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <!-- mybatis-plus-extension 分页插件 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>${mybatis-plus-extension.version}</version> </dependency> <!-- 阿里数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <!-- 阿里JSON解析器 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!--swagger3--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>${springfox-swagger3.version}</version> </dependency> <!--由于使用Swagger,这俩个jar包版本过低,现升级为2.0--> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-core</artifactId> <version>${swagger3.version}</version> </dependency> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-metadata</artifactId> <version>${swagger3.version}</version> </dependency> <!-- Knife4j --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>${knife4j.version}</version> </dependency> <!--lombok 是一个工具类库,可以用简单的注解形式来简化代码。--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <!--freemarker--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit-test.version}</version> <scope>test</scope> </dependency> <!-- 校验密码模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>password-check</artifactId> <version>${dt.version}</version> </dependency> <!-- 点通有数模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-data-presented</artifactId> <version>${dt.version}</version> </dependency> <!-- 登录认证模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-auth</artifactId> <version>${dt.version}</version> </dependency> <!-- 初始化模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> <version>${dt.version}</version> </dependency> </dependencies> </dependencyManagement> <!--打 jar 包--> <build> <plugins> <!-- maven聚合项目父工程必须要引用的插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <!--跳过 test,因为 nacos yaml 文件中的的中文打包 test 会报错--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build> </project>
1.2 sc-common 中 pom.xml 内容介绍
1 packaging
pom.xml 中有一些特殊的地方需要介绍一下。
作为顶级父类,打包方式一定是 pom,其他子项目不写默认是 jar
<!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 --> <packaging>pom</packaging>
2 modules
作为顶级父类,要把所有子模块引入,其中启动模块: sc-start 和 初始化模块: sc-initialize 是启动项目时必须要有的,其他业务模块根据需要引入,建议全部业务模块都引入,不会影响后续打包操作。
<!-- 需要引入的子模块 --> <modules> <!-- 启动模块(必须) --> <module>sc-start</module> <!-- 初始化模块(必须) --> <module>sc-initialize</module> <!-- 密码校验模块 --> <module>password-check</module> <!-- 登录认证模块 --> <module>sc-auth</module> <!-- 点通有数模块 --> <module>sc-data-presented</module> </modules>
3 dependencyManagement & dependencies
**dependencyManagement:**只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
<dependencyManagement> ... </dependencyManagement>
**dependencies:**是依赖传递,即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
**注:**依赖声明和依赖传递是不一样的,顶级父类 sc-conmon 中的 pom 只是做一个依赖声明。依赖传递的话,是通过初始化模块 sc-initialize :这里引用一堆的外部包,然后其它项目就引用,就能做到依赖传递。
你可以将自己项目需要用到的所有包或者公共的包都统一管理在 sc-initialize 的 pom.xml 中。
<dependencies>....</dependencies>
总结:
如果父pom中使用的是
<dependencyManagement> <dependencies>....</dependencies></dependencyManagement>
的方式,则子pom不会自动使用父pom中的jar包,这时如果子pom想使用的话,就要给出groupId和artifactId,无需给出version。
如果父pom中使用的是
<dependencies>....</dependencies>
的方式,则子pom,或者其他依赖的项目会自动使用pom中的jar包。
2、新项目创建
2.1 创建Maven多模块项目
整体模块如下:
1 创建父工程模块
先建立外层父工程 sc-common : File →new →project 选择 Spring Initializr → Next下一步到以下页面填写父工程信息
接下来就是一直 Next 到项目创建完成
工程结构如下,记得配置自己的 maven 相关地址:
接下来,把src整个删掉,父工程不需要,因为父工程你就当它只有一个外壳就完了,然后在把完整的 pom.xml 的内容全部复制进去。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的。 这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 --> <modelVersion>4.0.0</modelVersion> <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。--> <groupId>com.dt.cloud</groupId> <!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID。 在某个特定的group ID下,artifact ID也必须是唯一的。--> <artifactId>sc-common</artifactId> <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 --> <version>0.0.1-SNAPSHOT</version> <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 --> <packaging>pom</packaging><!--项目的名称, Maven产生的文档用 --> <name>sc-common</name> <!-- 项目的详细描述--> <description>点通软件的基础模块</description> <!-- 需要引入的子模块 --> <modules> <!-- 启动模块(必须) --> <module>sc-start</module> <!-- 初始化模块(必须) --> <module>sc-initialize</module> <!-- 密码校验模块 --> <module>password-check</module> <!-- 登录认证模块 --> <module>sc-auth</module> <!-- 点通有数模块 --> <module>sc-data-presented</module> </modules> <!--项目开发者属性,目前用来做版本声明 --> <properties> <!--点通 sc-common 版本 --> <dt.version>0.0.1-SNAPSHOT</dt.version> <!-- springboot 版本 --> <spring-boot.version>2.5.3</spring-boot.version> <!-- spring-cloud 版本 --> <spring-cloud.version>2020.0.3</spring-cloud.version> <!-- spring-security 版本 --> <spring-security.version>5.5.3</spring-security.version> <!-- jwt 版本 --> <jwt.version>0.9.1</jwt.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <!-- jdk 版本 --> <java.version>1.8</java.version> <!-- 阿里巴巴 fastjson 版本 --> <fastjson.version>1.2.75</fastjson.version> <!-- 阿里巴巴 easyexcel 版本 --> <easyexcel.version>2.1.6</easyexcel.version> <!-- swagger 相关 版本 --> <springfox-swagger2.version>2.6.1</springfox-swagger2.version> <springfox-swagger-ui.version>2.6.1</springfox-swagger-ui.version> <springfox-swagger3.version>3.0.0</springfox-swagger3.version> <swagger3.version>2.0.0.RELEASE</swagger3.version> <!-- knife4j 版本 --> <knife4j.version>3.0.2</knife4j.version> <!-- 数据库连接池 版本 --> <druid.version>1.1.22</druid.version> <!-- 数据库 版本 --> <mysql.version>8.0.20</mysql.version> <!-- mybatis-plus相关 版本 --> <mybatis-plus.version>3.3.2</mybatis-plus.version> <mybatis-plus-extension.version>3.4.0</mybatis-plus-extension.version> <!-- junit 单元测试 版本 --> <junit-test.version>2.5.3</junit-test.version> <!-- lombok 版本 --> <lombok.version>1.18.2</lombok.version> <!-- nacos 版本 --> <nacos.version>2.1.2.RELEASE</nacos.version> <!-- freemarker 版本 --> <freemarker.version>2.3.30</freemarker.version> <!-- redis 版本 --> <redis.version>2.5.6</redis.version> <!-- jedis 版本 --> <jedis.version>3.6.3</jedis.version> <!-- apache http连接池 httpclient --> <httpclient.version>4.5.13</httpclient.version> <jackson-databind.version>2.12.4</jackson-databind.version> </properties> <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。--> <dependencyManagement> <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。--> <dependencies> <!-- SpringBoot的依赖配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- SpringCloud 微服务 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${nacos.version}</version> </dependency> <!-- 配置中心支持 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${nacos.version}</version> </dependency> <!-- springsecurity --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${spring-security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring-security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring-security.version}</version> </dependency> <!-- jwt --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jwt.version}</version> </dependency> <!-- mybatis-plus 增强CRUD --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <!-- mybatis-plus-extension 分页插件 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>${mybatis-plus-extension.version}</version> </dependency> <!-- 阿里数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <!-- 阿里JSON解析器 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!-- 阿里操作 excel 的 easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>${easyexcel.version}</version> </dependency> <!--swagger3--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>${springfox-swagger3.version}</version> </dependency> <!--由于使用Swagger,这俩个jar包版本过低,现升级为2.0--> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-core</artifactId> <version>${swagger3.version}</version> </dependency> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-metadata</artifactId> <version>${swagger3.version}</version> </dependency> <!-- Knife4j --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>${knife4j.version}</version> </dependency> <!--lombok 是一个工具类库,可以用简单的注解形式来简化代码。--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <!--freemarker--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> <!-- 单元测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <version>${junit-test.version}</version> <scope>test</scope> </dependency> <!-- redis--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${redis.version}</version> </dependency> <!-- java操作 redis 的 jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <!-- redis 序列化--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson-databind.version}</version> </dependency> <!-- apache http连接池 httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency> <!-- 校验密码模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>password-check</artifactId> <version>${dt.version}</version> </dependency> <!-- 点通有数模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-data-presented</artifactId> <version>${dt.version}</version> </dependency> <!-- 登录认证模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-auth</artifactId> <version>${dt.version}</version> </dependency> <!-- 初始化模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> <version>${dt.version}</version> </dependency> </dependencies> </dependencyManagement> <!--打 jar 包--> <build> <plugins> <!-- maven聚合项目父工程必须要引用的插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <!--跳过 test,因为 nacos yaml 文件中的的中文打包 test 会报错--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build> </project>
因为这些子模块还没有创建,所以 pom.xml 中报错是正常的。接下来让我们开始创建子工程模块。
2 创建子模块
鼠标放在父工程上右键 → new → Module 选择Spring Initaializr 下一步填写子工程信息。
删除每个子模块中没用的文件,.mvn、.gitignore、daoiml、mvnw、mvnw.cmd文件只留下pom.xml
除了启动子模块 sc-start,其他子模块都要删除启动类和配置文件
子模块中的 test 文件夹需要删掉,因为这个模块没有任何业务,不需要单元测试
注:创建父工程是创建一个新的项目,子工程是在父工程上创建新的 Module。别搞错了哦!!!
2.1 启动模块:sc-start**主要功能:**项目的启动入口,负责其他子模块的引用,项目的打包,项目的配置文件管理。
在启动模块 sc-start --->resource 中引入配置文件和日志文件:
bootstarp.yaml 内容如下:
# -----------启动参数----------- server-addr: 192.168.124.63:9048 namespace: feature-sr05-island-test group: service-cool service-config: sc-password-check.yaml common-config: sc-common.yaml # -----------启动参数----------- server: address: 0.0.0.0 port: 9002 spring: application: name: sc-common #这里和项目名称对应 cloud: nacos: config: server-addr: ${server-addr} namespace: ${namespace} # 服务特有配置文件 name: ${service-config} group: ${group} file-extension: yaml shared-configs: # common配置文件 - data-id: ${common-config} group: ${group} refresh: true discovery: namespace: ${namespace} server-addr: ${server-addr} group: ${group} service: ${sc.app-name}-${spring.application.name} loadbalancer: retry: enabled: true jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 default-property-inclusion: non_null datasource: type: com.alibaba.druid.pool.DruidDataSource druid: url: ${business-database.url:jdbc:mysql://${business-database.host}:${business-database.port}/${business-database.database-name}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8} username: ${business-database.username} password: ${business-database.password} driver-class-name: ${business-database.driver-class-name:com.mysql.cj.jdbc.Driver} initial-size: 8 min-idle: 1 max-active: 20 max-wait: 60000 time-between-eviction-runsMillis: 60000 min-evictable-idle-timeMillis: 300000 validation-query: select 1 FROM DUAL pool-prepared-statements: true max-open-prepared-statements: 20 max-pool-prepared-statement-per-connection-size: 20 filters: stat connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis: 5000 use-global-data-source-stat: true # 邮箱配置 mail: host: smtp.qq.com username: 1046470145@qq.com password: gemwiiyxydeebebc default-encoding: UTF-8 port: 587 properties: mail: smtp: auth: true socketFactory: class: javax.net.ssl.SSLSocketFactory # redis 配置 redis: database: 0 host: ${redis.host} lettuce: pool: max-active: 8 #最大连接数据库连接数,设 0 为没有限制 max-idle: 8 #最大等待连接中的数量,设 0 为没有限制 max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制 min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 shutdown-timeout: 100ms password: ${redis.password} port: ${redis.port} config: server-addr: ${server-addr} mybatis: mapper-locations=classpath: mapper/*Mapper.xml feign: hystrix: enabled: false httpclient: enabled: true okhttp: enabled: false hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 10000 ribbon: ConnectTimeout: 50000 ReadTimeout: 50000 OkToRetryOnAllOperations: true MaxAutoRetriesNextServer: 2 MaxAutoRetries: 1 management: endpoints: web: exposure: include: '*' log: path: logs logging: config: classpath:logback-spring.xml level: com: alibaba: nacos: client: naming: error config: impl: ClientWorker: error #file: /dev/stdout local-config: read: timeout: 5000 debug: mode: test log: mode: console level: info swagger: enable: true applicationName: sc-common applicationDescription: 点通公用模块 applicationVersion: v1.0 tryHost: null mybatis-plus: configuration: call-setters-on-nulls: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 30
logback-spring.xml 内容如下:
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> <!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true --> <!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。 当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="true" scanPeriod="60 seconds"> <contextName>logback</contextName> <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 --> <!--日志存储路径--> <property name="log.path" value="./logs" /> <!--输出到 部署 控制台--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>debug</level> </filter> <encoder> <!-- 时间 | 线程名 | 日志级别 | 类->方法名:行数 : 日志信息 --> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %t | %highlight(%-5level) | %logger{50}->%M:%L : %msg%n</Pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--输出到 idea 控制台--> <appender name="CONSOLE_DEV" class="ch.qos.logback.core.ConsoleAppender"> <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>debug</level> </filter> <encoder> <!-- 时间 | 线程名 | 日志级别 | 类:行数| 日志信息 --> <Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} | %t | %highlight(%-5level) | \(%class{0}.java:%L\) | %msg%n</Pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--输出到文档--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文档的路径及文档名 --> <file>${log.path}/info.log</file> <!--日志文档输出格式--> <encoder> <!-- 时间 | 线程名 | 日志级别 | 类->方法名:行数 : 日志信息 --> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %t | %-5level | %logger{50}->%M:%L : %msg%n</Pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/info/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文档保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> </appender> <!--输出到warn日志到文档--> <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> <!-- 正在记录的日志文档的路径及文档名 --> <file>${log.path}/warn.log</file> <!--日志文档输出格式--> <encoder> <!-- 时间 | 线程名 | 日志级别 | 类->方法名:行数 : 日志信息 --> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %t | %-5level | %logger{50}->%M:%L : %msg%n</Pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文档保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> </appender> <!--开发环境使用--> <!-- <root level="info">--> <!-- <appender-ref ref="CONSOLE_DEV" />--> <!-- <appender-ref ref="FILE" />--> <!-- </root>--> <!--部署环境使用使用--> <root level="info"> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> <appender-ref ref="FILE_WARN" /> </root> </configuration>
替换启动模块中的 pom.xml 为以下内容:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>sc-common</artifactId> <groupId>com.dt.cloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sc-start</artifactId> <name>start</name> <description>sc-common 启动类</description> <!-- 打包方式 --> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> </dependency><!-- 校验密码模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>password-check</artifactId> </dependency> <!-- 点通有数模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-data-presented</artifactId> </dependency> <!-- 登录认证模块 --> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-auth</artifactId> </dependency> <!--SpringCloud 2.4版本 之后不再 优先读取bootstrap文件,导致bootstrap不起作用。 需要在pom.xml文件中引入如下依赖后,就可以正常读取bootstrap.yml配置文件了--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.1.RELEASE</version> <configuration> <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!--<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <warName>${project.artifactId}</warName> </configuration> </plugin>--> </plugins> <finalName>sc-common</finalName> </build> </project>
修改父工程为:
<parent> <artifactId>sc-common</artifactId> <groupId>com.dt.cloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent>
启动模块打包方式:
<!-- 打包方式 --> <packaging>jar</packaging>
启动依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
引入初始化模块(未创建,稍后创建):
<!-- 初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> </dependency>
根据实际情况引入其他业务模块。这里引入哪个模块,就会在打包的时候带上哪个业务模块的代码,可以选择性组装功能。
加入 build 标签内容:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.1.RELEASE</version> <configuration> <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> <finalName>sc-common</finalName> </build>
给启动加上对应注解:
@EnableDiscoveryClient /** * basePackages:指定要扫描的Mapper类的包的路径。 * 如果不通子模块下的 mapper 不在同一个路径下,需要配置多个路径 */ @MapperScan(basePackages ={"com.dt.**.mapper"}) /** * scanBasePackages: Spring扫描 @Controller,@Service,@Component,@Repository 等注解的基 础包路径 * 如果不通子模块的包路径不一致,需要配置多个路径,所以建议用统一路径:com.dt.cloud * exclude: 排除此类的AutoConfig,即禁止 SpringBoot 自动注入数据源配置。 */ @SpringBootApplication(scanBasePackages = {"com.dt.cloud"}, exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class }) public class ScStartApplication { public static void main(String[] args) { SpringApplication.run(ScStartApplication.class, args); } }
到这里,启动模块就构建完毕了。
2.2 初始化模块:sc-initialize主要功能:管理所有模块的公共依赖关系,初始化项目的所有 config 如Swagger,mybatisplus,等,初始化项目中所有公共变量,管理公共业务模块,数据库操作模块,bean ,工具类,返回值封装等。
一句话:所有公共的东西都能放这里统一管理,这样就不用每个子模块都实现一遍了。建议超过两个子模块引用的业务就放在这个初始化模块下。其他模块只需要引入 sc-initialize 即可获取他的功能及依赖
创建初始化模块 sc-initialize:
记得删除启动类和配置文件,然后创建对应的功能目录:
引入初始化的 pom.xml :
这里就是一些公共的依赖,没有其他多余的标签。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>sc-common</artifactId> <groupId>com.dt.cloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent><artifactId>sc-initialize</artifactId> <!-- 打包方式 --> <!-- <packaging>jar</packaging>--> <description>点通启动类</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- 配置中心支持 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- mybatis-plus 增强CRUD --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> </dependency> <!-- 阿里数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <!-- Mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--swagger3--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>${springfox-swagger3.version}</version> </dependency> <!--由于使用Swagger,这俩个jar包版本过低,现升级为2.0--> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-core</artifactId> </dependency> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-metadata</artifactId> </dependency> <!-- Knife4j --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.15</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.13</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.55</version> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </dependency> <!-- jedis 连接池--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!-- redis 序列化--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> <!-- springsecurity --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <!-- jwt --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> <!-- RestTemplate 的 http 连接池--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> </dependencies> </project>
- 引入所有业务子模块
**注意:**这里第一个模块 (password-check) 需要启动类,其他模块是不需要启动类的,所以要把其他模块的启动类删掉。第一个模块作为启动类,他的 pom.xml 与其他模块也是不同,这个下面再说。
2.3 启动项目:看效果到这一步,我们就可以把项目运行起来了
此时访问 swagger 文档地址:http://localhost:9003/doc.html ,可以看到,项目整合swagger完全没有问题了,接下来就整点业务子模块。
2.4 业务模块:password-check
重复上面的操作,创建业务子模块 password-check ,删掉多余的文件,得到干净的子模块目录如下:
修改 pom.xml 如下:
非常的干净清爽,只需要引入初始化模块即可。后面有业务需要,在引入特定的依赖,也不会污染到其他模块,造成依赖管理混乱。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>sc-common</artifactId> <groupId>com.dt.cloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>password-check</artifactId> <name>password-check</name> <description>业务子模块 password-check </description> <dependencies> <!--引入初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
接下来,把之前 password-check 模块也业务复制过来即可。由于 password-check 模块与其他模块有很多重复内容,我把它们都提取到初始化模块 sc-initialize 中作为公共内容了。最后的目录如下:
是不是很清爽,也就是说,以后我们写代码,只要基础环境搭建好了,我们就专心写业务代码就好了。在也不用担心模块兼容性,不同配置,不同工具类,不通返回值等等一大堆的问题,也不会出现一堆乱七八糟的依赖,每个模块下还是不同的版本,也不会出现每个模块的返回值不一样,日志配置不同,最后导致做模块整合的时候很痛苦了。
最后我们把需要的业务依赖导入到 pom.xml 中:
像 postgresql 这种数据库依赖,我们也可以考虑放到初始化模块 sc-initialize模块的 pom.xml 中统一管理,但是目前其他模块没有用到 postgresql ,所以就暂时放到 passward-check 业务模块的 pom.xml 中。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>sc-common</artifactId> <groupId>com.dt.cloud</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>password-check</artifactId> <name>password-check</name> <description>业务子模块 password-check </description> <dependencies> <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.13</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.4.6</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-ecs</artifactId> <version>4.17.6</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-dyvmsapi</artifactId> <version>1.2.2</version> </dependency> <!--spring boot actuator 监控组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> <!--Postgre--> <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <!--引入初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
然后我们在重启项目,访问 swagger 看看效果。
可以看到,swagger 中已经成功显示了 password-check 模块中的内容。接下来把其他业务模块都创建出来。
2.4 业务模块:sc-data-presented同理可得
2.6 业务模块:sc-auth同理可得
sc-auth 中需要用到 sc-data-presented 模块的业务内容,所以除了引入初始化模块 sc-initialize 模块,还需要额外引入 sc-data-presented :
<!--点通初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> </dependency> <!--点通有数模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-data-presented</artifactId> </dependency>
**注意:**每个模块都可以调用其他模块,但是两个模块之间不能互相调用,比如 sc-auth 中可以调用 sc-data-presented 中的业务,引入 sc-data-presented 依赖即可。但是此时要是 sc-data-presented 也引用 sc-auth 的业务,就会出现相互引用的死循环。解决办法是吧互相调用两方中任意一方的业务放到初始化模块 sc-initialize 中,这样就不会出现互相调用而造成的死循环了。
一句话概括:两个模块之间相互引用会出现依赖死循环
2.7 启动项目:看最终效果完美,各个模块的功能接口都出来了。
3 整合 flyway
sc-common 引入依赖,进行版本管理
<!-- flyway 自动升级SQL脚本 --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>${flyway.version}</version> </dependency> <!-- flyway 版本 --> <flyway.version>5.2.4</flyway.version>
初始化模块:sc-initialize pom.xml 引入 flyway 依赖
<!-- flyway 数据库脚本升级 --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
启动模块 sc-start 加入 flyway 配置文件
# flyway 配置 flyway: # 启用(true)或禁用(false) flyway enabled: true # flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。 clean-disabled: true # SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migration locations: classpath:db/migration # metadata 版本控制信息表 默认 flyway_schema_history table: flyway_schema_history # 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令 # 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。 baseline-on-migrate: true # 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略 baseline-version: 1 # 字符编码 默认 UTF-8 encoding: UTF-8 # 是否允许不按顺序迁移 开发建议 true 生产建议 false out-of-order: false # 需要 flyway 管控的 schema list,这里我们配置为 flyway. 缺省的话, 使用spring.datasource.url 配置的那个 schema, # 可以指定多个schema, 但仅会在第一个schema下建立 metadata 表, 也仅在第一个schema应用migration sql 脚本. # 但flyway Clean 命令会依次在这些schema下都执行一遍. 所以 确保生产 spring.flyway.clean-disabled 为 true # 简单来说 schemas 就是指定在哪个数据库里面执行 sql 文件,这里可以指定多个,注释掉默认是取 bootstrap.yaml 中配置的数据库 # schemas: service_cool_dev_v1 # 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常 validate-on-migrate: true
每个业务模块创建 目录: db/migration 用来专门存放业务模块中的SQL。
命名规范:V 20220224.01__create_report.sql
解析:大写V + 年 + 月 + 日 + 点符合( . ) + 版本号(防止同一天有多个sql修改) + 两个下划线( __ ) + 描述(中文或者英文都行)
2.2 初始化模块功能说明
初始化公共模块为:sc-initialize 。里面存放的是一些公共功能,大家要多加熟悉,防止出现一个功能两份代码。
1 公共配置
目前公共配置如下,已有的公共配置,不允许睡意修改,业务模块直接使用相关功能即可。
//Redis使用 FastJson 序列化,防止中文出现乱码 FastJson2JsonRedisSerializer //Mybatis Plus 配置 MybatisPlusConfig //Mybatis Plus 对数据库每条记录的创建时间和更新时间自动进行填充 MyMetaObjectHandler //redis 配置 RedisConfig // RestTemplate配置,用于服务之间进行通信 RestTemplateConfig //Swagger配置类 + 整合Knife4j SwaggerConfig
2 公共常量
//用于启动类配置的常量 ConfigConstants //系统处理返回网络请求状态码 HttpStatus
3、公共的 bean 实体类
基本上是对应我们数据表中的实体类,这样多个业务操作同一个表,就不用每次都去创建实体类了,后续还会加上更多的实体类。
// customer_company 表实体类 CustomerBean // customer_preferences 表实体类 CustomerPreferences // customer_User + customer_company 表实体类 CustomerUser //queue 表实体类 Queue // system_param_config 表实体类 SystemParamConfig //服务人员+客户用户所有信息实体类 SysUser //user_preferences 表实体类 UserPreferences //user 表实体类 Users // 登录用户身份权限信息 LoginUser //分页返回值封装 bean ResList //返回值封装 bean Result //接口状态码枚举 StatusCodeEnum //用户类型枚举 UserTypeEnum
4、公共业务功能功能
//customer_preferences 表的相关操作 CustomerPreferencesMapper //根据客户用户id查询客户用户偏好 CustomerUserMapper //queue 表的相关操作 QueueMapper //根据服务人员ID查询权限&根据客户用户ID查询权限 SysMenuMapper //system_param_config 表的相关操作 SystemParamConfigMapper // user_preferences 表的相关操作 UserPreferencesMapper // 根据服务人员id查询服务人员偏好 UsersMapper
5、公共工具类
//数据表 big 字段转换 为 int BigIntegerConverter //时间戳转换器 TimestampConverter //异常相关工具类 execption //spring工具类 方便在非spring管理环境中获取bean SpringUtils //使用Base64进行对字符串加解密 Base64Util //excel导出工具类 ExcelUtil //获取i18n资源文件,获取国际化翻译值 MessageUtils //redis操作工具类 RedisCache //Spring RestTemplate的请求方法工具类 RestTemplateUtil //安全服务工具类 SecurityUtils //字符串操作工具类 StringUtil
2.3 新建子模块注意事项
新建一个业务模块需处做哪些事情?
1、引入新建子模块
最外层的pom.xml中引入新建子模块
2、 sc-start 中加入配置文件
如果有配置,需要在 sc-start ---> bootstrap.yaml 中加入配置文件
3、注入依赖到sc-start
把自己注入到 sc-start 模块中,如果不需要打包,直接去掉依赖即可
4、引入初始化模块依赖
在新建业务子模块的 pom.xml 中引入初始化模块 sc-initialize 的依赖
<!-- 初始化模块--> <dependency> <groupId>com.dt.cloud</groupId> <artifactId>sc-initialize</artifactId> </dependency>
5、编写代码
到这里,就能愉快的编写代码了。对了,初始化模块中的公共功能别忘记使用哦!
常见问题
swagger 规范问题
项目引入 swagger 文档就是为了方便前端&后端&测试快速交互,这样只要定义好入参,返回值,就可以出接口文档,接下来前端后端及测试就可以并行去开发。如果大家没有按标准去使用 swagger 文档注解,这势必会回到手写文档的时代。而且还会引发后续一系列的问题,比如代码后期维护交接困难,没有问题的代码,只能进到业务文档里面去看实际效果。本地排查问题也全靠猜。所以为了方便大家的工作,开发的时候务必要话时间去打磨好这个 swagger 接口文档。
1、返回值 bean 中没有写 swagger注解,如下:
正确的写法如下:
每个入参 bean 都需要配上相对应的注解描述
@ApiModel @ApiModelProperty
2、返回值 bean 的嵌套类型没有写相关注解,导致嵌套类型解析不出来,如下:
嵌套在 List 里面的 DataSetParamDto 实体类没有写注解。
导致 swagger 看到的文档效果是这样的:
3、入参是 Map 或者是 JSONObject
除非是不可抗拒的历史原因,否则强制要求开发人员把入参封装为 bean。这不仅仅是为了方便整合 swagger 文档,这也是 java 封装的一大特性。特别是刚入职场的新人,要避免存在这个问题。对于前后端数据交互,推荐阅读这篇文档:https://www.cnblogs.com/panlei3707/p/11208811.html
2 数据库相关问题
1、建表语句
引入 flyway 之后,V1 版本允许建表语句出现,后面的所有版本都是围绕表结构的增删改。每次对表结构的修改,要记录为一个 sql 文件,而不是把旧表删除,创建新表。新表一定是相关的旧表过渡而来。
2、文件命名规范及存放
sql 文件命名规范遵循 flyway 命名规范,放在业务模块的 resources/db/migration 下,命名为:
V 20220224.01__create_report.sql
解析:大写V + 年 + 月 + 日 + 点符合( . ) + 版本号(防止同一天有多个sql修改) + 两个下划线( __ ) + 描述(中文或者英文都行)
3、漏写注释问题
对于每个类,每个方法,每个 bean 实体类 的作用,我们都应该做一个注释,让人一眼看下去,就知道是它的大概作用。特别是对应数据表的每一个 bean ,要么用 @TableName("表名") 标准对应的是哪个表,要么就在注释用写明是基于哪个表生成的 bean, 特别是连表,复杂的 bean 实体类, 要标注清楚,每个字段要写上注释。
4、返回值封装问题
不同项目,所用不同的返回值封装。返回值封装无好坏之分,但是为了统一格式,统一代码风格,后续开发一律要使用 sc-initialize 中 entity/vo/ 下面的 ResList和 Result 作为返回值封装类型。
- 聚合 Spring boot + maven项目打包和linux部署
- SpringBoot+Docker实现项目的Maven打包&镜像构建&容器中运行==简单自动化部署
- Springboot中如何导入本地jar包,并通过maven把项目成功打包成jar包部署
- Springboot中引入本地jar包,并通过maven把项目成功打包成jar包部署
- springboot项目的打包部署(gralde和maven)
- Spring Boot项目使用IDEA编辑器和Maven打包并在Docker部署
- SpringBoot项目使用maven打包成war方式,部署到外部Tomcat~
- springboot项目的打包部署(gralde和maven)
- Springboot中如何引入本地jar包,并通过maven把项目成功打包成jar包部署
- idea快速创建maven集成spring-boot项目
- Intellij IDEA创建SpringBoot maven项目步骤
- 聚合maven+spring-boot打包可执行jar
- spring boot 创建maven多模块项目(一)
- SpringBoot项目打包使用的Maven插件
- spring boot 创建maven多模块项目(二)
- maven-如何使用maven对springboot项目进行打包
- idea springBoot + maven 项目打包 在linux上执行
- 在SpringBoot 中创建Maven项目
- 一、IDEA创建Spring Boot Maven项目
- Spring Boot项目打包部署到外置tomcat并运行