2025-微服务—SpringCloud-1~3
2025-微服务—SpringCloud
- 第一章、从Boot和Cloud版本选型开始说起
- 1、Springboot版本
- 2、Springcloud版本
- 3、Springcloud Alibaba
- 4、本次讲解定稿版
- 第二章 关于Cloud各种组件的停更/升级/替换
- 1、微服务介绍
- 2、SpringCloud是什么?能干吗?产生背景?
- 3、本次讲解定稿,速通版
- 4、Netflix OSS被移除的原因
- 5、2024第三季(新版)
- 第三章 微服务架构编码Base工程模块构建
- 1、订单→支付,业务需求说明
- 2、约定 > 配置 > 编码
- 3、IDEA新建Project和Maven父工程
- 4、Mapper4之一键生成
- 5、Rest通用Base工程构建
- 6、引入微服务理念,从这里开始
- 7、**为什么要引入微服务**
第一章、从Boot和Cloud版本选型开始说起
-- 各个版本
Java17+
cloud 2023.0.0
boot 3.2.0
cloud alibaba 2022.0.0.0-RC2
Maven 3.9+
Mysql 8.0+ //不许捣蛋,上述全部版本必须按照要求
1、Springboot版本
springBoot git源码地址
springBoot官网
查看springBoot版本

SpringBoot3.0崛起
通过上面官网发现,Boot官方强烈建议你使用Java17+升级到3.X以上版本
2、Springcloud版本
Springcloud git源码地址
Springcloud官网
Cloud命名规则
SpringCloud的版发展史
Spring Cloud 采用了英国伦敦地铁站英国伦敦地铁站的名称来命名,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本
SpringCloud是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本号混淆,
SpringCloud版本采用了名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如Angel是第一个版本, Brixton是第二个版本。
当SpringCloud的发布内容积累到临界点或者一个重大BUG被解决后,会发布一个"service releases"版本,简称SRX版本,比如Greenwich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。

springcloud(截至2025.1.9)

Spring Cloud

3、Springcloud Alibaba
查看Spring Cloud Alibaba版本—官网

有延后情况,非最新版(不推荐)
SpringCloud Alibaba官网Github说明
毕业版本依赖关系(推荐使用)
Spring Cloud Alibaba版本 参考文档
版本选择

4、本次讲解定稿版
Java17+
cloud 2023.0.0
boot 3.2.0
cloud alibaba 2022.0.0.0-RC2
Maven 3.9+
Mysql 8.0+
SpringCloud VS SpringCloud VS SpringCloud Alibaba版本三者制约对应关系
若同时用boot和cloud,由话事人cloud决定boot版本

注:Spring cloud Alibaba毕业版本依赖关系(推荐使用)
第二章 关于Cloud各种组件的停更/升级/替换
SpringBoot3 小白零基础教程视频
零基础微服务架构理论入门视频
1、微服务介绍
2、SpringCloud是什么?能干吗?产生背景?
让程序员专注于业务逻辑,有第3方支援

3、本次讲解定稿,速通版

4、Netflix OSS被移除的原因

Netflix哪些被移除了?

Spring Cloud Netflix项目进入维护模式 停更不停用;
–被动修复bugs;不再接受合并请求;不再发布新版本
由停更引发的“升级惨案”
2018第一季(旧版)

2020第二季(旧版)
备注: 如果被remove掉的组件,不再使用。
5、2024第三季(新版)

第三章 微服务架构编码Base工程模块构建
1、订单→支付,业务需求说明

2、约定 > 配置 > 编码
1)什么是约定?
springboot springcloud用什么版本
springcloud组件用哪些,约定好pom工程
2)配置
能用配置的就用配置,少动手编码
maven配置,maven测试,yml文件配置
3)编码?
多动手编码(一看就会,一做就废,从入门到劝退。)

3、IDEA新建Project和Maven父工程
微服务cloud整体聚合Maven父工程Project
Maven父工程步骤:
1)New Project

2) 聚合总父工程名字

3)字符编码

4) 注解生效激活

5) java编译版本选17

6) File Type过滤

父工程POM文件内容:
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><hutool.version>5.8.22</hutool.version><lombok.version>1.18.26</lombok.version><druid.version>1.1.20</druid.version><mybatis.springboot.version>3.0.2</mybatis.springboot.version><mysql.version>8.0.11</mysql.version><swagger3.version>2.2.0</swagger3.version><mapper.version>4.2.3</mapper.version><fastjson2.version>2.0.40</fastjson2.version><persistence-api.version>1.0.2</persistence-api.version><spring.boot.test.version>3.1.5</spring.boot.test.version><spring.boot.version>3.2.0</spring.boot.version><spring.cloud.version>2023.0.0</spring.cloud.version><spring.cloud.alibaba.version>2022.0.0.0-RC2</spring.cloud.alibaba.version></properties><dependencyManagement><dependencies><!--springboot 3.2.0--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency><!--springcloud 2023.0.0--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--springcloud alibaba 2022.0.0.0-RC2--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!--SpringBoot集成mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.springboot.version}</version></dependency><!--Mysql数据库驱动8 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--SpringBoot集成druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!--通用Mapper4之tk.mybatis--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>${mapper.version}</version></dependency><!--persistence--><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>${persistence-api.version}</version></dependency><!-- fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>${fastjson2.version}</version></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>${swagger3.version}</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><optional>true</optional></dependency><!-- spring-boot-starter-test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>${spring.boot.test.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement>
</project>
Maven工程落地细节复习
Maven中的DependencyManagement和Dependencies
dependencyManagement Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。
通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。
使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。
Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个
dependencyManagement 元素中指定的版本号。

这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,
优势:
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的,只有在子项目中写了该依赖项并且没有指定具体版本,才会从父项目中继承该项 且version和scope都读取自父pom;
如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
maven中跳过单元测试
1)配置
< build > <!-- maven 中跳过单元测试 -->< plugins >< plugin >< groupId >org.apache.maven.plugins </ groupId >< artifactId >maven-surefire-plugin </ artifactId >< configuration >< skip >true </ skip ></ configuration ></ plugin ></ plugins >
</ build >
2)IDEA工具支持(推荐)

mysql驱动说明
Mysql5
# mysql5.7---JDBC四件套
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.user = root
jdbc.password =123456# Maven的POM文件处理
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version>
</dependency>
Mysql8
# mysql8.0---JDBC四件套
jdbc.driverClass = com.mysql.cj.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
jdbc.user = root
jdbc.password =123456# Maven的POM
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version>
</dependency>
4、Mapper4之一键生成
mybatis-generator官网
本次使用Mapper4 MyBatis通用Mapper4官网
下一代:MyBatis 通用 Mapper5官网
一键生成步骤
db2024库t_pay支付信息表SQL
DROP TABLE IF EXISTS `t_pay`;CREATE TABLE `t_pay` (`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,`pay_no` VARCHAR(50) NOT NULL COMMENT '支付流水号',`order_no` VARCHAR(50) NOT NULL COMMENT '订单流水号',`user_id` INT(10) DEFAULT '1' COMMENT '用户账号ID',`amount` DECIMAL(8,2) NOT NULL DEFAULT '9.9' COMMENT '交易金额',`deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='支付交易表';INSERT INTO t_pay(pay_no,order_no) VALUES('pay17203699','6544bafb424a');SELECT * FROM t_pay;
Module
普通Maven工程— mybatis_generator2024
POM
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><!--我自己独一份,只是一个普通Maven工程,与boot和cloud无关--><artifactId>mybatis_generator2024</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--Mybatis 通用mapper tk单独使用,自己独有+自带版本号--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.13</version></dependency><!-- Mybatis Generator 自己独有+自带版本号--><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.4.2</version></dependency><!--通用Mapper--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId></dependency><!--mysql8.0--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--persistence--><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><resources><resource><directory>${basedir}/src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>${basedir}/src/main/resources</directory></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.2</version><configuration><configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile><overwrite>true</overwrite><verbose>true</verbose></configuration><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>4.2.3</version></dependency></dependencies></plugin></plugins></build></project>
配置
src\main\resources路径下新建: config.properties
mysql5
#User表包名
package.name=com.atguigu.cloud
# mysql5.7
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.user = root
jdbc.password =123456
mysql8
#t_pay表包名
package.name=com.atguigu.cloud# mysql8.0
jdbc.driverClass = com.mysql.cj.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
jdbc.user = root
jdbc.password =123456
src\main\resources路径下新建: generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><properties resource="config.properties"/><context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"><property name="beginningDelimiter" value="`"/><property name="endingDelimiter" value="`"/><plugin type="tk.mybatis.mapper.generator.MapperPlugin"><property name="mappers" value="tk.mybatis.mapper.common.Mapper"/><property name="caseSensitive" value="true"/></plugin><jdbcConnection driverClass="${jdbc.driverClass}"connectionURL="${jdbc.url}"userId="${jdbc.user}"password="${jdbc.password}"></jdbcConnection><javaModelGenerator targetPackage="${package.name}.entities" targetProject="src/main/java"/><sqlMapGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java"/><javaClientGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java" type="XMLMAPPER"/><table tableName="t_pay" domainObjectName="Pay"><generatedKey column="id" sqlStatement="JDBC"/></table></context>
</generatorConfiguration>
一键生成:
双击插件mybatis-generator:gererate,
一键生成entity+mapper接口+xml实现SQL

5、Rest通用Base工程构建
工程V1
cloud-provider-payment8001 微服务提供者支付Module模块
微服务小口诀:
1 建module
2 改POM
3 写YML
4 主启动
5 业务类
步骤
建module
建普通Maven模块 cloud-provider-payment8001


创建完成后请回到父工程查看pom文件变化
改POM
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-provider-payment8001</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--SpringBoot集成druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!-- Swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency><!--mybatis和springboot整合--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--Mysql数据库驱动8 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--persistence--><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId></dependency><!--通用Mapper4--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!-- fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency><!--test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
写YML
server:port: 8001# ==========applicationName + druid-mysql8 driver===================
spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: 123456# ========================mybatis===================
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.cloud.entitiesconfiguration:map-underscore-to-camel-case: true
业务类
将之前一键生成的代码直接拷贝进8001模块
entities
主实体Pay
搜索便笺
package com.atguigu.cloud.entities;import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.*;/*** 表名:t_pay* 表注释:支付交易表
*/
@Table(name = "t_pay")
public class Pay {@Id@GeneratedValue(generator = "JDBC")private Integer id;/*** 支付流水号*/@Column(name = "pay_no")private String payNo;/*** 订单流水号*/@Column(name = "order_no")private String orderNo;/*** 用户账号ID*/@Column(name = "user_id")private Integer userId;/*** 交易金额*/private BigDecimal amount;/*** 删除标志,默认0不删除,1删除*/private Byte deleted;/*** 创建时间*/@Column(name = "create_time")private Date createTime;/*** 更新时间*/@Column(name = "update_time")private Date updateTime;/*** @return id*/public Integer getId() {return id;}/*** @param id*/public void setId(Integer id) {this.id = id;}/*** 获取支付流水号** @return payNo - 支付流水号*/public String getPayNo() {return payNo;}/*** 设置支付流水号** @param payNo 支付流水号*/public void setPayNo(String payNo) {this.payNo = payNo;}/*** 获取订单流水号** @return orderNo - 订单流水号*/public String getOrderNo() {return orderNo;}/*** 设置订单流水号** @param orderNo 订单流水号*/public void setOrderNo(String orderNo) {this.orderNo = orderNo;}/*** 获取用户账号ID** @return userId - 用户账号ID*/public Integer getUserId() {return userId;}/*** 设置用户账号ID** @param userId 用户账号ID*/public void setUserId(Integer userId) {this.userId = userId;}/*** 获取交易金额** @return amount - 交易金额*/public BigDecimal getAmount() {return amount;}/*** 设置交易金额** @param amount 交易金额*/public void setAmount(BigDecimal amount) {this.amount = amount;}/*** 获取删除标志,默认0不删除,1删除** @return deleted - 删除标志,默认0不删除,1删除*/public Byte getDeleted() {return deleted;}/*** 设置删除标志,默认0不删除,1删除** @param deleted 删除标志,默认0不删除,1删除*/public void setDeleted(Byte deleted) {this.deleted = deleted;}/*** 获取创建时间** @return createTime - 创建时间*/public Date getCreateTime() {return createTime;}/*** 设置创建时间** @param createTime 创建时间*/public void setCreateTime(Date createTime) {this.createTime = createTime;}/*** 获取更新时间** @return updateTime - 更新时间*/public Date getUpdateTime() {return updateTime;}/*** 设置更新时间** @param updateTime 更新时间*/public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}
}
传递数值PayDTO
package com.atguigu.cloud.entities;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;/*** @auther zzyy* @create 2023-11-03 18:58*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayDTO implements Serializable
{private Integer id;//支付流水号private String payNo;//订单流水号private String orderNo;//用户账号IDprivate Integer userId;//交易金额private BigDecimal amount;
}
mapper
Mapper接口PayMapper
package com.atguigu.cloud.mapper;import com.atguigu.cloud.entities.Pay;
import tk.mybatis.mapper.common.Mapper;public interface PayMapper extends Mapper<Pay> {
}
映射文件PayMapper.xml
src\main\resources路径下,新建文件夹mapper。
拷贝PayMapper.xml进上一步的mapper文件夹
PayMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.cloud.mapper.PayMapper"><resultMap id="BaseResultMap" type="com.atguigu.cloud.entities.Pay"><!--WARNING - @mbg.generated--><id column="id" jdbcType="INTEGER" property="id" /><result column="pay_no" jdbcType="VARCHAR" property="payNo" /><result column="order_no" jdbcType="VARCHAR" property="orderNo" /><result column="user_id" jdbcType="INTEGER" property="userId" /><result column="amount" jdbcType="DECIMAL" property="amount" /><result column="deleted" jdbcType="TINYINT" property="deleted" /><result column="create_time" jdbcType="TIMESTAMP" property="createTime" /><result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /></resultMap>
</mapper>
service
服务接口PayService
package com.atguigu.cloud.service;import com.atguigu.cloud.entities.Pay;import java.util.List;/*** @auther zzyy* @create 2023-11-03 18:40*/
public interface PayService
{public int add(Pay pay);public int delete(Integer id);public int update(Pay pay);public Pay getById(Integer id);public List<Pay> getAll();
}
实现类PayServiceImpl
package com.atguigu.cloud.service.impl;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.mapper.PayMapper;
import com.atguigu.cloud.service.PayService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;import java.util.List;/*** @auther zzyy* @create 2023-11-03 18:44*/
@Service
public class PayServiceImpl implements PayService{@ResourcePayMapper payMapper;@Overridepublic int add(Pay pay){return payMapper.insertSelective(pay);}@Overridepublic int delete(Integer id){return payMapper.deleteByPrimaryKey(id);}@Overridepublic int update(Pay pay){return payMapper.updateByPrimaryKeySelective(pay);}@Overridepublic Pay getById(Integer id){return payMapper.selectByPrimaryKey(id);}@Overridepublic List<Pay> getAll(){return payMapper.selectAll();}
}
controller
package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.service.PayService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;/*** @auther zzyy* @create 2023-11-03 18:55*/
@RestController
public class PayController{@Resource PayService payService;@PostMapping(value = "/pay/add")public String addPay(@RequestBody Pay pay){System.out.println(pay.toString());int i = payService.add(pay);return "成功插入记录,返回值:"+i;}@DeleteMapping(value = "/pay/del/{id}")public Integer deletePay(@PathVariable("id") Integer id) {return payService.delete(id);}@PutMapping(value = "/pay/update")public String updatePay(@RequestBody PayDTO payDTO){Pay pay = new Pay();BeanUtils.copyProperties(payDTO, pay);int i = payService.update(pay);return "成功修改记录,返回值:"+i;}@GetMapping(value = "/pay/get/{id}")public Pay getById(@PathVariable("id") Integer id){return payService.getById(id);}//全部查询getall作为家庭作业
}
测试
PostMan
add
{"payNo": "17204076","orderNo": "6544de1c424a","userId": "2","amount": "19.90"
}

json测试字段和我们的entity实体类字段一一对应

delete

update

select

Swagger3

Controller 使用@Tag

修改PayController
package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.service.PayService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;/*** @auther zzyy* @create 2023-11-03 18:55*/
@RestController
@Tag(name = "支付微服务模块",description = "支付CRUD")
public class PayController
{@ResourcePayService payService;@PostMapping(value = "/pay/add")@Operation(summary = "新增",description = "新增支付流水方法,json串做参数")public String addPay(@RequestBody Pay pay){System.out.println(pay.toString());int i = payService.add(pay);return "成功插入记录,返回值:"+i;}@DeleteMapping(value = "/pay/del/{id}")@Operation(summary = "删除",description = "删除支付流水方法")public Integer deletePay(@PathVariable("id") Integer id) {return payService.delete(id);}@PutMapping(value = "/pay/update")@Operation(summary = "修改",description = "修改支付流水方法")public String updatePay(@RequestBody PayDTO payDTO){Pay pay = new Pay();BeanUtils.copyProperties(payDTO, pay);int i = payService.update(pay);return "成功修改记录,返回值:"+i;}@GetMapping(value = "/pay/get/{id}")@Operation(summary = "按照ID查流水",description = "查询支付流水方法")public Pay getById(@PathVariable("id") Integer id){return payService.getById(id);}//全部查询getall作为家庭作业
}
方法
@Operation
entity或者DTO
@Schema

含分组迭代的Config配置类
Swagger3Config
package com.atguigu.cloud.config;import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @auther zzyy* @create 2023-11-04 10:40*/
@Configuration
public class Swagger3Config
{@Beanpublic GroupedOpenApi PayApi(){return GroupedOpenApi.builder().group("支付微服务模块").pathsToMatch("/pay/**").build();}@Beanpublic GroupedOpenApi OtherApi(){return GroupedOpenApi.builder().group("其它微服务模块").pathsToMatch("/other/**", "/others").build();}/*@Beanpublic GroupedOpenApi CustomerApi(){return GroupedOpenApi.builder().group("客户微服务模块").pathsToMatch("/customer/**", "/customers").build();}*/@Beanpublic OpenAPI docsOpenApi(){return new OpenAPI().info(new Info().title("cloud2024").description("通用设计rest").version("v1.0")).externalDocs(new ExternalDocumentation().description("www.atguigu.com").url("https://yiyan.baidu.com/"));}
}
调用方式
http://localhost:8001/swagger-ui/index.html
上述模块还有那些问题
1、时间格式问题
时间日志格式的统一和定制情况?

2、Java如何设计API接口实现统一格式返回?
影响前端/小程序/app等交互体验和开发
void、数值、String、对象entity、Map …
看看目前程序返回值情况
故意写了多种返回类值
3、全局异常接入返回的标准格式
有统一返回值+全局统一异常
工程V2
cloud-provider-payment8001 微服务提供者支付Module模块V2改进版++
1 解决:时间格式问题
/*** 创建时间*/
@Column(name = "create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;/*** 更新时间*/
@Column(name = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;

2 解决:统一返回值
思路:

步骤: 新建枚举类ReturnCodeEnum
HTTP请求返回的状态码

ReturnCodeEnum
package com.atguigu.cloud.resp;import lombok.Getter;import java.util.Arrays;/*** @auther zzyy* @create 2023-11-04 11:51*/
@Getter
public enum ReturnCodeEnum
{/**操作失败**/RC999("999","操作XXX失败"),/**操作成功**/RC200("200","success"),/**服务降级**/RC201("201","服务开启降级保护,请稍后再试!"),/**热点参数限流**/RC202("202","热点参数限流,请稍后再试!"),/**系统规则不满足**/RC203("203","系统规则不满足要求,请稍后再试!"),/**授权规则不通过**/RC204("204","授权规则不通过,请稍后再试!"),/**access_denied**/RC403("403","无访问权限,请联系管理员授予权限"),/**access_denied**/RC401("401","匿名用户访问无权限资源时的异常"),RC404("404","404页面找不到的异常"),/**服务异常**/RC500("500","系统异常,请稍后重试"),RC375("375","数学运算异常,请稍后重试"),INVALID_TOKEN("2001","访问令牌不合法"),ACCESS_DENIED("2003","没有权限访问该资源"),CLIENT_AUTHENTICATION_FAILED("1001","客户端认证失败"),USERNAME_OR_PASSWORD_ERROR("1002","用户名或密码错误"),BUSINESS_ERROR("1004","业务逻辑异常"),UNSUPPORTED_GRANT_TYPE("1003", "不支持的认证模式");/**自定义状态码**/private final String code;/**自定义描述**/private final String message;ReturnCodeEnum(String code, String message){this.code = code;this.message = message;}//遍历枚举V1public static ReturnCodeEnum getReturnCodeEnum(String code){for (ReturnCodeEnum element : ReturnCodeEnum.values()) {if(element.getCode().equalsIgnoreCase(code)){return element;}}return null;}//遍历枚举V2public static ReturnCodeEnum getReturnCodeEnumV2(String code){return Arrays.stream(ReturnCodeEnum.values()).filter(x -> x.getCode().equalsIgnoreCase(code)).findFirst().orElse(null);}/*public static void main(String[] args){System.out.println(getReturnCodeEnumV2("200"));System.out.println(getReturnCodeEnumV2("200").getCode());System.out.println(getReturnCodeEnumV2("200").getMessage());}*/
}
新建统一定义返回对象ResultData
ResultData
package com.atguigu.cloud.resp;import lombok.Data;
import lombok.experimental.Accessors;/*** @auther zzyy* @create 2023-11-04 11:59*/
@Data
@Accessors(chain = true)
public class ResultData<T> {private String code;/** 结果状态 ,具体状态码参见枚举类ReturnCodeEnum.java*/private String message;private T data;private long timestamp ;public ResultData (){this.timestamp = System.currentTimeMillis();}public static <T> ResultData<T> success(T data) {ResultData<T> resultData = new ResultData<>();resultData.setCode(ReturnCodeEnum.RC200.getCode());resultData.setMessage(ReturnCodeEnum.RC200.getMessage());resultData.setData(data);return resultData;}public static <T> ResultData<T> fail(String code, String message) {ResultData<T> resultData = new ResultData<>();resultData.setCode(code);resultData.setMessage(message);return resultData;}}
修改PayController
package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import com.atguigu.cloud.service.PayService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;/*** @auther zzyy* @create 2023-11-12 22:34*/
@RestController
@Tag(name = "支付微服务模块",description = "支付CRUD")
public class PayController
{@ResourcePayService payService;@PostMapping(value = "/pay/add")@Operation(summary = "新增",description = "新增支付流水方法,json串做参数")public ResultData<String> addPay(@RequestBody Pay pay){System.out.println(pay.toString());int i = payService.add(pay);return ResultData.success("成功插入记录,返回值:"+i);}@DeleteMapping(value = "/pay/del/{id}")@Operation(summary = "删除",description = "删除支付流水方法")public ResultData<Integer> deletePay(@PathVariable("id") Integer id) {int i = payService.delete(id);return ResultData.success(i);}@PutMapping(value = "/pay/update")@Operation(summary = "修改",description = "修改支付流水方法")public ResultData<String> updatePay(@RequestBody PayDTO payDTO){Pay pay = new Pay();BeanUtils.copyProperties(payDTO, pay);int i = payService.update(pay);return ResultData.success("成功修改记录,返回值:"+i);}@GetMapping(value = "/pay/get/{id}")@Operation(summary = "按照ID查流水",description = "查询支付流水方法")public ResultData<Pay> getById(@PathVariable("id") Integer id){Pay pay = payService.getById(id);return ResultData.success(pay);}//全部查询getall作为家庭作业
}
测试 :http://localhost:8001/pay/get/1
结论: 通过ResultData.success()对返回结果进行包装后返回给前端
优化驱动力 ???
查询方法写个bug
if(id == -4) throw new RuntimeException(“id不能为负数”);
3 解决:全局异常接入返回的标准格式

新建全局异常类GlobalExceptionHandler
package com.atguigu.cloud.exp;import com.atguigu.cloud.resp.ResultData;
import com.atguigu.cloud.resp.ReturnCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** @auther zzyy* @create 2023-11-04 12:20*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler
{/*** 默认全局异常处理。* @param e the e* @return ResultData*/@ExceptionHandler(RuntimeException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ResultData<String> exception(Exception e) {System.out.println("----come in GlobalExceptionHandler");log.error("全局异常信息exception:{}", e.getMessage(), e);return ResultData.fail(ReturnCodeEnum.RC500.getCode(),e.getMessage());}
}
修改Controller
package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import com.atguigu.cloud.resp.ReturnCodeEnum;
import com.atguigu.cloud.service.PayService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;/*** @auther zzyy* @create 2023-12-12 22:34*/
@RestController
@Tag(name = "支付微服务模块",description = "支付CRUD")
public class PayController
{@ResourcePayService payService;@PostMapping(value = "/pay/add")@Operation(summary = "新增",description = "新增支付流水方法,json串做参数")public ResultData<String> addPay(@RequestBody Pay pay){System.out.println(pay.toString());int i = payService.add(pay);return ResultData.success("成功插入记录,返回值:"+i);}@DeleteMapping(value = "/pay/del/{id}")@Operation(summary = "删除",description = "删除支付流水方法")public ResultData<Integer> deletePay(@PathVariable("id") Integer id) {int i = payService.delete(id);return ResultData.success(i);}@PutMapping(value = "/pay/update")@Operation(summary = "修改",description = "修改支付流水方法")public ResultData<String> updatePay(@RequestBody PayDTO payDTO){Pay pay = new Pay();BeanUtils.copyProperties(payDTO, pay);int i = payService.update(pay);return ResultData.success("成功修改记录,返回值:"+i);}@GetMapping(value = "/pay/get/{id}")@Operation(summary = "按照ID查流水",description = "查询支付流水方法")public ResultData<Pay> getById(@PathVariable("id") Integer id){if(id == -4) throw new RuntimeException("id不能为负数");Pay pay = payService.getById(id);return ResultData.success(pay);}//全部查询getall作为家庭作业@RequestMapping(value = "/pay/error",method = RequestMethod.GET)public ResultData<Integer> getPayError(){Integer i = Integer.valueOf(200);try{System.out.println("--------come here");int data = 10/0;}catch (Exception e){e.printStackTrace();return ResultData.fail(ReturnCodeEnum.RC500.getCode(),e.getMessage());}return ResultData.success(i);}
}
目前工程目录结构

6、引入微服务理念,从这里开始
订单微服务80如何才能调用到支付微服务8001?
cloud-consumer-order80微服务调用者订单Module模块
- 建cloud-consumer-order80
- 改POM
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-consumer-order80</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--web + actuator--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool-all--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--fastjson2--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
- 写YML
server:port: 80
- 主启动(修改Main类名为Main80)
package com.atguigu.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @auther zzyy* @create 2023-11-04 15:19*/
@SpringBootApplication
public class Main80
{public static void main(String[] args){SpringApplication.run(Main80.class,args);}
}
- 业务类
entities
传递数值PayDTO
package com.atguigu.cloud.entities;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;/*** @auther zzyy* @create 2023-11-04 15:28** 一般而言,调用者不应该获悉服务提供者的entity资源并知道表结构关系,所以服务提供方给出的接口文档都都应成为DTO*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayDTO implements Serializable
{private Integer id;//支付流水号private String payNo;//订单流水号private String orderNo;//用户账号IDprivate Integer userId;//交易金额private BigDecimal amount;
}
ResultData统一返回值也从8001拷贝进来
RestTemplate
RestTemplate 是什么?
RestTemplate提供了多种便捷访问远程Http服务的方法,
是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集
RestTemplate 官网
RestTemplate 常用API使用说明
使用说明
使用restTemplate访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class) 这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

getForObject方法/getForEntity方法
返回对象为响应体中数据转化成的对象,基本上可以理解为Json

返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等

postForObject/postForEntity

GET请求方法
<T> T getForObject(String url, Class<T> responseType, Object... uriVariables);<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);<T> T getForObject(URI url, Class<T> responseType);<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables);<T> ResponseEntity<T> getForEntity(URI var1, Class<T> responseType);
POST请求方法
<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);<T> T postForObject(URI url, @Nullable Object request, Class<T> responseType);<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);<T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType);
config配置类
package com.atguigu.cloud.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*** @auther zzyy* @create 2023-11-04 15:57*/
@Configuration
public class RestTemplateConfig
{@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
controller
package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;/*** @auther zzyy* @create 2023-11-04 16:00*/
@RestController
public class OrderController{public static final String PaymentSrv_URL = "http://localhost:8001";//先写死,硬编码@Autowiredprivate RestTemplate restTemplate;/*** 一般情况下,通过浏览器的地址栏输入url,发送的只能是get请求* 我们底层调用的是post方法,模拟消费者发送get请求,客户端消费者* 参数可以不添加@RequestBody* @param payDTO* @return*/@GetMapping("/consumer/pay/add")public ResultData addOrder(PayDTO payDTO){return restTemplate.postForObject(PaymentSrv_URL + "/pay/add",payDTO,ResultData.class);}// 删除+修改操作作为家庭作业,O(∩_∩)O。。。。。。。@GetMapping("/consumer/pay/get/{id}")public ResultData getPayInfo(@PathVariable("id") Integer id){return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+id, ResultData.class, id);}
}
- Postman测试
http://localhost/consumer/pay/get/1
http://localhost/consumer/pay/addpayNo=1213&orderNo=1213&userId=2&amount=3.33
作业:删除+修改操作
工程重构
观察问题—系统中有重复部分,重构


新建Module
1.cloud-api-commons
2.对外暴露通用的组件/api/接口/工具类等
改POM
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV6</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-api-commons</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency></dependencies></project>
entities
- PayDTO
- 统一返回

全局异常类,可加可不加,酌情
maven命令clean install

订单80和支付8001分别改造
- 删除各自的原先有过的entities和统一返回体等内容
- 各自粘贴POM内容
<!-- 引入自己定义的api通用包 -->
<dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
80
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-consumer-order80</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- 引入自己定义的api通用包 --><dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--web + actuator--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool-all--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--fastjson2--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
8001
<?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><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-provider-payment8001</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- 引入自己定义的api通用包 --><dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--SpringBoot集成druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!-- Swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency><!--mybatis和springboot整合--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--Mysql数据库驱动8 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--persistence--><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId></dependency><!--通用Mapper4--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!-- fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency><!--test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
postman测试
http://localhost/consumer/pay/get/1
http://localhost/consumer/pay/add?payNo=1213&orderNo=1213&userId=2&amount=3.33
作业: 删除+修改操作
目前工程样图

截至到目前,没有引入任何 SpringCloud 相关内容
7、为什么要引入微服务
上一步controller问题???
硬编码写死问题

微服务所在的IP地址和端口号 硬编码 到订单微服务中,会存在非常多的问题
(1)如果订单微服务和支付微服务的IP地址或者端口号发生了变化,则支付微服务将变得不可用,需要同步修改订单微服务中调用支付微服务的IP地址和端口号。
(2)如果系统中提供了多个订单微服务和支付微服务,则无法实现微服务的负载均衡功能。
(3)如果系统需要支持更高的并发,需要部署更多的订单微服务和支付微服务,硬编码订单微服务则后续的维护会变得异常复杂。
所以,在微服务开发的过程中,需要引入服务治理功能,实现微服务之间的动态注册与发现,从此刻开始我们正式进入SpringCloud实战。
相关文章:
2025-微服务—SpringCloud-1~3
2025-微服务—SpringCloud 第一章、从Boot和Cloud版本选型开始说起1、Springboot版本2、Springcloud版本3、Springcloud Alibaba4、本次讲解定稿版 第二章 关于Cloud各种组件的停更/升级/替换1、微服务介绍2、SpringCloud是什么?能干吗?产生背景…...
UnityXR Interaction Toolkit 如何检测HandGestures
前言 随着VR设备的不断发展,从最初的手柄操作,逐渐演变出了手部交互,即头显可以直接识别玩家的手部动作,来完成手柄的交互功能。我们今天就来介绍下如何使用Unity的XR Interaction Toolkit 来检测手势Hand Gesture。 环境配置 1.使用Unity 2021或者更高版本,创建一个项…...
使用 Multer 上传图片到阿里云 OSS
文件上传到哪里更好? 上传到服务器本地 上传到服务器本地,这种方法在现今商业项目中,几乎已经见不到了。因为服务器带宽,磁盘 IO 都是非常有限的。将文件上传和读取放在自己服务器上,并不是明智的选择。 上传到云储存…...
2008-2020年各省社会消费品零售总额数据
2008-2020年各省社会消费品零售总额数据 1、时间:2008-2020年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区、年份、社会消费品零售总额 4、范围:31省 5、指标解释:社会消费品零售总额指企业&#x…...
【大模型入门指南 07】量化技术浅析
【大模型入门指南】系列文章: 【大模型入门指南 01】深度学习入门【大模型入门指南 02】LLM大模型基础知识【大模型入门指南 03】提示词工程【大模型入门指南 04】Transformer结构【大模型入门指南 05】LLM技术选型【大模型入门指南 06】LLM数据预处理【大模型入门…...
java 查询树结构数据,无限层级树结构通用方法
1、数据库表数据 2、controller层TestTree简单测试 RestController RequestMapping("/test") public class testTreeController {Autowiredprivate TestTreeService testTreeService;GetMapping("/list")public List<TestTree> List(TestTree tree)…...
FreeCAD集成gmsh源码分析
目录 gmsh模块界面获取gmsh的版本执行gmsh网格划分gmsh模块界面 这个界面是用PySide来写的,PySide是QT的python绑定,具体代码在task_mesh_gmsh.py文件中。目前这个界面非常的简陋,没有对接gmsh稍微高级一点的功能。界面对应的事件处理是在gmshtools.py中。这里只分析“Gmsh …...
K8s 集群 IP 地址管理指南(K8s Cluster IP Address Management Guide)
K8s 集群 IP 地址管理指南 概述 你是否在小型初创公司或大型企业工作,并正在为公司评估 Kubernetes?你可能正在考虑运行十几个或更多的 Kubernetes (K8s) 集群。你期望每个集群支持几百个 K8s 节点,每个节点可能有 50 到 100 个 K8s Pod。这…...
Debye-Einstein-模型拟合比热容Python脚本
固体比热模型中的德拜模型和爱因斯坦模型是固体物理学中用于估算固体热容的两种重要原子振动模型。 爱因斯坦模型基于三种假设:1.晶格中的每一个原子都是三维量子谐振子;2.原子不互相作用;3.所有的原子都以相同的频率振动(与德拜…...
OpenCV的图像分割
1、基本概念 图像分割是计算机视觉和图像处理中的一个关键步骤,它指的是将图像划分为多个区域或对象的过程。这些区域或对象在某种特性(如颜色、形状、纹理或亮度等)上是一致的或相似的,而在不同区域之间则存在明显的差异。图像分…...
【源码+文档+调试讲解】农产品研究报告管理系统
摘 要 农产品研究报告管理系统是一个旨在收集、整理、存储和分析农产品相关研究数据的综合性平台。农产品研究报告管理系统通常包含一个强大的数据库,它能够处理大量的研究数据,并对这些数据进行有效的管理和备份。农产品研究报告管理系统是现代农业科学…...
【STM32-学习笔记-7-】USART串口通信
文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…...
高可用虚拟IP-keepalived
个人觉得华为云这个文档十分详细:使用虚拟IP和Keepalived搭建高可用Web集群_弹性云服务器 ECS_华为云 应用场景:虚拟IP技术。虚拟IP,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个…...
AI多模态技术介绍:视觉语言模型(VLMs)指南
本文作者:AIGCmagic社区 刘一手 AI多模态全栈学习路线 在本文中,我们将探讨用于开发视觉语言模型(Vision Language Models,以下简称VLMs)的架构、评估策略和主流数据集,以及该领域的关键挑战和未来趋势。通…...
高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
目录 高效工作流:用Mermaid绘制你的专属流程图 一、流程图的使用场景 1.1、流程图flowChart 1.2、使用场景 二、如何使用mermaid画出优雅的流程图 2.1、流程图添加图名 2.2、定义图类型与方向 2.3、节点形状定义 2.3.1、规定语法 2.3.2、不同节点案例 2.…...
uniApp通过xgplayer(西瓜播放器)接入视频实时监控
🚀 个人简介:某大型国企资深软件开发工程师,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~ 💟 作 者:码喽的自我修养ǹ…...
ws 配置 IngressRoute 和 http一样
ws 配置 IngressRoute 和 http一样 apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata:name: web-ws-ingressroutenamespace: starp spec:entryPoints:- webroutes:- match: Host(webws.we…...
IMX6ULL的IOMUXC寄存器和SNVS复用寄存器似乎都是对引脚指定复用功能的,那二者有何区别?
IMX6ULL 的 IOMUXC 和 SNVS(Secure Non-Volatile Storage)复用寄存器都是用于配置引脚功能的,但它们的作用范围、目的和使用场景存在明显区别。以下是它们的差异分析: 1. IOMUXC(I/O Multiplexer Control)寄…...
LabVIEW实现动态水球图的方法
水球图是一种直观展示百分比数据的图表,常用于数据监测与展示。LabVIEW 虽不直接支持水球图绘制,但可通过图片控件动态绘制波形,或借助 HTMLCSS 的 Web 控件实现。此外,还可以结合 Python 等第三方工具生成水球图,LabV…...
【江协STM32】11-2/3 W25Q64简介、软件SPI读写W25Q64
1. W25Q64简介 W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、字库存储、固件程序存储等场景存储介质:Nor Flash(闪存)时钟频率:80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI)存储容…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

