SpringCloud学习 (一)前置知识学习

2024-09-04 12:36

本文主要是介绍SpringCloud学习 (一)前置知识学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

微服务的概念

微服务架构就是吧一个大系统按业务功能分解成多个职责单一的小系统,每一个小模块尽量专一地只做一件事情,并利用简单的方法使得多个小系统相互协作,组合成一个大系统之后再统一对外提供整体服务。

SpringCloud的主要维度

  1. 服务注册与发现
  2. 服务调用和负载均衡
  3. 分布式事务
  4. 服务熔断和降级
  5. 服务链路追踪
  6. 服务网关
  7. 分布式配置管理

附:Swagger3的使用

常用注解

  • @Tag:标注在controller类上,用于标识controller的作用
  • @Parameter:标注在参数旁,用于标注参数的作用
  • @Parameters:标注在参数旁,用于参数的多重说明
  • @Schema:标注在model层的JavaBean,用于描述模型作用以及每个属性的作用
  • @Operation:标注在方法上,表述方法的作用
  • @ApiResponse:标注在方法上,描述相应状态码

注解案例:

controller类:

@RestController
@Slf4j
@Tag(name = "支付微服务模块",description = "支付crud")
public class PayController {@Resourceprivate PayService payService;@PostMapping(value = "/pay/add")@Operation(summary = "新增", description = "新增支付流水方法")public String addPay(@RequestBody Pay pay){int add = payService.add(pay);log.info("新增数据:" + pay.toString());return "成功插入记录";}@DeleteMapping("pay/del/{id}")@Operation(summary = "删除", description = "删除支付流水方法")public Integer deletePay(@PathVariable("id") Integer id){int delete = payService.delete(id);log.info("删除数据的id:" + id);return delete;}@PutMapping("/pay/update")@Operation(summary = "更新", description = "修改支付流水方法")public String updatePay(@RequestBody PayDto payDto){Pay pay = new Pay();BeanUtils.copyProperties(payDto,pay);int update = payService.update(pay);log.info("成功更新记录" + payDto);return "成功更新记录";}@GetMapping("/pay/get/{id}")@Operation(summary = "查询", description = "查询支付流水方法")public PayDto getById(@PathVariable("id") Integer id){Pay byId = payService.getById(id);PayDto payDto = new PayDto();BeanUtils.copyProperties(byId,payDto);log.info("查询记录:" + payDto);return payDto;}@GetMapping("/pay/getAll")@Operation(summary = "查询所有", description = "查询所有的支付流水")public List<PayDto> getAll(){List<Pay> all = payService.getAll();List<PayDto> collect = all.stream().map((item) -> {PayDto payDto = new PayDto();BeanUtils.copyProperties(item, payDto);return payDto;}).collect(Collectors.toList());log.info("查询记录:" + collect);return collect;}
}

实体类:

@Table(name = "t_pay")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(title = "支付实体")
public class Pay {@Id@GeneratedValue(generator = "JDBC")@Schema(title = "主键id")private Integer id;/*** 支付流水号*/@Column(name = "pay_no")@Schema(title = "支付流水号")private String payNo;/*** 订单流水号*/@Column(name = "order_no")@Schema(title = "订单流水号")private String orderNo;/*** 用户账号ID*/@Column(name = "user_id")@Schema(title = "用户账号id")private Integer userId;/*** 交易金额*/@Schema(title = "交易金额")private BigDecimal amount;/*** 删除标志,默认0不删除,1删除*/@Schema(title = "默认删除标志")private Byte deleted;/*** 创建时间*/@Column(name = "create_time")@Schema(title = "创建时间")private Date createTime;/*** 更新时间*/@Column(name = "update_time")@Schema(title = "更新时间")private Date updateTime;
}

配置类的写法:

@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.ergou.com").url("<https://yiyan.baidu.com/>"));}
}

Swagger3调用方式:http://ip地址:端口/swagger-ui/index.html

附:定义响应返回标准格式

定义返回标准格式三大标配:

  • code状态值:由后端统一定义各种返回结果的状态码
  • message描述:本次接口调用的结果描述
  • data数据:本次返回的数据

拓展:有时候会加第四个,timestamp:接口调用返回时间

步骤

1.新建枚举类ReturnCodeEnum

http请求返回的状态码:

分类区间分类描述
1**100~199信息,服务器收到请求,需要请求者继续执行操作
2**200~299成功,操作被成功接收并处理
3**300~399重定向,需要进一步的操作以完成请求
4**400~499客户端错误,请求中包含语法错误或者无法完成请求
5**500~599服务器错误,服务器再处理请求的过程中发生了错误

ReturnCodeEnum枚举类:

@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;}//遍历枚举V1,传统版public static ReturnCodeEnum getReturnCodeEnum(String code){for (ReturnCodeEnum element : ReturnCodeEnum.values()) {if(element.getCode().equalsIgnoreCase(code)){return element;}}return null;}//遍历枚举V2,stream流式计算版public static ReturnCodeEnum getReturnCodeEnumV2(String code){return Arrays.stream(ReturnCodeEnum.values()).filter(x -> x.getCode().equalsIgnoreCase(code)).findFirst().orElse(null);}}

2.新建统一定义返回对象

@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;}}

3.新建全局异常处理器

@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());}
}

RestTemplate

RestTemplate提供了多种便捷访问远程Http的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集

使用restTemplate访问restful的接口有三个参数:

  • url:rest请求地址
  • responseType:http响应转换被转换成的类型
  • requestMap:请求参数

getForObject方法/getForEntity方法

如果返回对象为响应题中数据转换成的对象,也就是返回了一个json信息,并不包含响应头、响应状态码、响应体这种结构。就是使用getForObject方法。

如果返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等。就是使用getForEntity方法

参数有两个,第一个是url,第二个是json信息或者响应体中的信息对应的类型的类的class实例。如果有请求头之类的请求参数信息,可以加第三个参数传入相应的参数

PostForObject方法/postForEntity方法

与上述大致,不同的是,多了一个参数,即:第一个参数是url,第二个参数是接收请求体信息的对象,第三个参数是json信息或者响应体中的信息对应的类型的类的class实例。如果有请求头之类的请求参数信息,可以加第四个参数传入相应的参数

delete方法/put方法

delete只有一个参数,就是url。

put有两个参数,第一个是url,第二个是接收请求体信息的对象。

配置类

将RestTemplate的类型的对象加入到ioc容器

@Configuration
public class RestTemplateConfig
{@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}

使用案例

@RestController
public class OrderController {public static final String PaymentSrv_URL = "<http://localhost:8001>";@Resourceprivate RestTemplate restTemplate;@PostMapping("/consumer/pay/add")public ResultData addOrder(@RequestBody PayDTO payDto){return restTemplate.postForObject(PaymentSrv_URL + "/pay/add",payDto,ResultData.class);}@GetMapping("/consumer/pay/get/{id}")public ResultData getOrder(@PathVariable("id") int id){return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/" + id,ResultData.class);}@DeleteMapping("/consumer/pay/del/{id}")public ResultData deleteOrder(@PathVariable("id") int id){restTemplate.delete(PaymentSrv_URL + "/pay/del/" + id);return ResultData.success("成功删除");}@PutMapping("/consumer/pay/update")public ResultData updateOrder(@RequestBody PayDTO payDto){restTemplate.put(PaymentSrv_URL + "/pay/update",payDto);return ResultData.success("成功更新");}
}

通用模块

在多个微服务模块中,通常会有通用的一些部分,比如对外暴露通用的组件、api、接口、工具类等。

在将这些部分加入到通用模块中后,要clean+install做成通用包将其通用模块加入到maven本地仓库中去。

然后在pom文件中的dependcies中引入自己的通用包。

<!-- 引入自己定义的api通用包 -->
<dependency><groupId>com.ergou.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version>
</dependency>

这篇关于SpringCloud学习 (一)前置知识学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136036

相关文章

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt