跟着黑马微服务课程走的,是思路1,把不同服务的方法统一抽到一个公共模块中
在微服务中,如果一个服务需要请求另一个服务的接口,那么就会涉及到发起远程请求,但是手动发请求太麻烦,OpenFeign 提供了基于接口的声明式 REST 客户端,让开发者可以通过编写接口的方式来定义服务间的调用关系,而在实际执行时,OpenFeign 将根据这些定义自动生成代理对象,并处理请求的发送和接收。这种方式让开发者可以更加专注于业务逻辑的实现,而将远程调用的细节交给框架来处理。
OpenFeign 不一定非得配合服务发现/注册中心才能使用,但通常情况下,结合服务发现/注册中心可以更好地发挥 OpenFeign 的优势。这里使用Nacos作为服务发现注册中心。
1.创建模块
创建一个模块,假设命名为hm-api
其依赖如下
<?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">
<parent>
<artifactId>hmall</artifactId>
<groupId>com.heima</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hm-api</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!--open feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- load balancer-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- swagger 注解依赖 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
2.编写客户端
在模块中创一个client包,用来存放我们的客户端,每一个服务写一个单独的客户端,书写方式与contrller十分类似
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
@FeignClient("item-service") //这个注解必须加,参数为nacos上的对应服务名
public interface ItemClient {
//这里就按照controller里面写对应方法,注意把路径写全
@GetMapping("/items")
List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
@PutMapping("/items/stock/deduct")
void deductStock(@RequestBody List<OrderDetailDTO> items);
}
发现实体类报错了,那就把需要的,原本服务里面的实体拿过来
3.改造原本服务代码
在原本服务的pom中导入我们新的模块
<!--feign模块-->
<dependency>
<groupId>com.heima</groupId>
<artifactId>hm-api</artifactId>
<version>1.0.0</version>
</dependency>
在原本服务的启动类上加上注解@EnableFeignClients
在Service中,注入我们需要的Client,使用时,直接调用我们写好的方法就行,openFeign会向对应的服务发送请求(注意要把对应服务给启动)
@Service
@RequiredArgsConstructor
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {
// 如果用final,就加 @RequiredArgsConstructor 注解
// 否则,就用@Autowired注解来注入
private final UserClient userClient;
private final TradeClient tradeClient;
@Override
@Transactional
public void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO) {
// 1.查询支付单
PayOrder po = getById(payOrderFormDTO.getId());
// 2.判断状态
if(!PayStatus.WAIT_BUYER_PAY.equalsValue(po.getStatus())){
// 订单不是未支付,状态异常
throw new BizIllegalException("交易已支付或关闭!");
}
// 3.尝试扣减余额 这里调用到了其他服务的方法
userClient.deductMoney(payOrderFormDTO.getPw(), po.getAmount());
// 4.修改支付单状态
boolean success = markPayOrderSuccess(payOrderFormDTO.getId(), LocalDateTime.now());
if (!success) {
throw new BizIllegalException("交易已支付或关闭!");
}
// 5.修改订单状态 这里也用到了其他服务的方法
tradeClient.markOrderPaySuccess(po.getBizUserId());
}
}
至此,就可以快捷的发送请求到别的服务了
4.日志配置
OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:
NONE:不记录任何日志信息,这是默认值。
BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
在我们新建的模块下创建一个config包,定义一个日志配置类
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL;
}
}
如果想要日志级别在某一个Client中生效,那就在对应Client的接口类的注解中加入配置
@FeignClient(value = "your-service", configuration = DefaultFeignConfig.class)
如果想要全局生效,那就在服务中启动类的注解中配置
@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
标签:调用,服务,请求,OpenFeign,springframework,org,import,日志,远程
From: https://blog.csdn.net/YinLiaoEr/article/details/140473324