本文发布时间:2023-05-05
尚在学习当中,如有不足,请指正!!!
项目结构
本篇文章是之前项目的后续版本,前面的内容可看
链接:从0开始搭建一个微服务项(并注册到nacos)_bgbgking的博客-CSDN博客
因本篇内容较前篇跨幅较大,有兴趣可查看源码
链接:spring-cloud-demo: spring cloud基础架构及其组件的基本使用 (gitee.com)
正文
本篇主要介绍远程调用组件----openfeign的使用
首先肯定要介绍openfeign
官网介绍:
Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same used by default in Spring Web. Spring Cloud integrates Eureka, Spring Cloud CircuitBreaker, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.
中文意思:
Feign是一个声明式web服务客户端。它使编写web服务客户端更容易。要使用Feign,请创建一个接口并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并支持使用Spring Web中默认使用的注释。Spring Cloud集成了Eureka、Spring Cloud CircuitBreaker以及Spring Cloud LoadBalancer,在使用Feign时提供负载均衡的http客户端。
简单理解(个人拙见):
openfeign可以在代码中向另一个微服务接口发送请求并获得结果,然后再对结果进行封装等操作。
举例:小明想要送一颗糖给他妈妈,但是他没有糖也不会制作糖,而镇上的张三会做糖,他就叫家里的机器人去张三那帮他买糖。(举例很呆但还是要举)
小明-->当前微服务
机器人-->openfeign客户端
张三-->其他微服务
要理解为什么要使用远程调用
正正文
在当前微服务中引入依赖
demo项目中cloud-order里的service模块中需要进行远程调用,因此,在cloud-order-service的pom.xml文件中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
注意,我父工程引入了spring-cloud-dependencies,对其依赖版本进行了管理
创建openfeign客户端
import com.ailj.feign.result.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* name: nacos中注册的远程服务名称
* path: 远程调用controller类上的@RequestMapping中的内容
*/
@FeignClient(name = "goods-api",path = "/goods")
public interface GoodFeignServer {
@GetMapping("/{goodId}")
//@PathVariable中必须指定参数的值!!
//因为在自身的controller类中,springmvc会将路径变量和参数绑定
//但是feign会将方法中的参数转为http请求的参数,并将其拼接在url后或放到请求体中
//@PathVariable参数name和value是等效的
Goods getById(@PathVariable("goodId") Long goodId);
}
注意:openfeign需要搭配服务发现客户端使用!!!本项目使用nacos(小明总得知道张三家地址吧)
调用服务
import com.ailj.feign.result.Goods;
import com.ailj.feign.server.GoodFeignServer;
import com.ailj.mapper.OrderMapper;
import com.ailj.model.dto.OrderDetail;
import com.ailj.model.po.Order;
import com.ailj.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Resource
OrderMapper orderMapper;
@Resource
GoodFeignServer goodFeignServer;
@Override
public OrderDetail getByUserId(Long userId) {
Order order = orderMapper.getByUserId(userId);
OrderDetail orderDetail = new OrderDetail();
orderDetail.setOrder(order);
Long goodId = order.getGoodId();
//远程调用
Goods goods = goodFeignServer.getById(goodId);
//将返回的结果封装
orderDetail.setGoodName(goods.getName());
return orderDetail;
}
}
就可以用了?
nonono
还需要在当前微服务的启动类开启@EnableFeignClients注解(小明总得能用这机器人吧)
因为在cloud-order模块下,只有cloud-order-api模块中有启动类,所以
@EnableFeignClients
@SpringBootApplication
public class OrderApplication {
完毕!
po-->Order类
@Data
@ApiModel(value="Order对象")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
@ApiModelProperty(value = "用户id")
private Long userId;
@ApiModelProperty(value = "商品id")
private Long goodId;
@ApiModelProperty(value = "金额")
private BigDecimal amount;
}
dto-->OrderDetail类
@Data
public class OrderDetail implements Serializable {
private static final long serialVersionUID = 8551092480256481422L;
private Order order;
private String goodName;
}
启动cloud-goods和cloud-order
成功!!!
最后浅浅解释下po、dto、vo(别的不会)
PO(Persistant Object)持久对象:映射数据库表的对象(数据库里啥样就啥样)
DTO(Data Transfer Object)数据传输对象:业务层中po对象中的字段不够用,还需要加入其他字段然后再进行封装处理成的对象(数据库里没这个表,又嫌po字段少)
如:
VO(Value Object)值对象:展现给页面层的对象
如:
还是它,但是概念不同
over
更深层的内容就请自行挖掘了