什么是Feign:

  1. SpringCloud提供的伪http客户端(本质还是用http),封装了Http调用流程,更适合面向接口化
  2. 让用Java接口注解的方式调用Http请求.
  3. 不用像Ribbon中通过封装HTTP请求报文的方式调用 Feign默认集成了Ribbon
  4. Nacos支持Feign,可以直接集成实现负载均衡的效果

原先ribbon存在的问题

  1. 不规范,风格不统一,维护性比较差。
  2. 比如在订单服务调用视频服务,url都是拼接的,很麻烦.

集成Feign实现远程方法调用

在订单服务的POM中添加依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

在订单服务的启动类增加注解@EnableFeignClients

  1. //开启Feign支持
  2. @EnableFeignClients
  3. //开启服务发现
  4. @EnableDiscoveryClient
  5. @SpringBootApplication
  6. public class OrderApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(OrderApplication.class, args);
  9. }
  10. //此处若不需要可以删掉
  11. @Bean
  12. @LoadBalanced
  13. public RestTemplate getRestTemplate(){
  14. return new RestTemplate();
  15. }
  16. }

添加订单服务的service接口
image.png

  1. import com.study.pojo.Video;
  2. import org.springframework.cloud.openfeign.FeignClient;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.RequestParam;
  5. //将视频服务名称添加
  6. @FeignClient(name="class-video-service")
  7. public interface OrderService {
  8. //写上路径,自动会携带参数
  9. @GetMapping("/api/v1/video/find_by_id")
  10. Video findById(@RequestParam("videoId") int videoId);
  11. }

改造订单服务Controller

  1. @RestController
  2. @RequestMapping("/api/v1/video_order")
  3. public class OrderController {
  4. @Autowired
  5. private OrderService orderService;
  6. @GetMapping("/save")
  7. public Object save(int videoId){
  8. //访问视频服务
  9. Video video = orderService.findById(videoId);
  10. //构造返回对象
  11. VideoOrder videoOrder = new VideoOrder();
  12. videoOrder.setVideoId(videoId);
  13. videoOrder.setVideoTitle(video.getTitle());
  14. videoOrder.setCreateTime(video.getCreateTime());
  15. return videoOrder;
  16. }
  17. }

post方式对象传输 Open-Feign 实现远程方法调用

视频服务中添加一个POST接口

  1. //插入 - 此处参数为了方便,只传了一个id
  2. @PostMapping("/insert")
  3. public void insert(@RequestBody Video video){
  4. //为了方便,只是打印了一下参数
  5. System.out.println("视频标题:" + video.getTitle());
  6. }

订单服务中的service接口增加方法

  1. //插入 - 传递对象到视频服务
  2. @PostMapping("/api/v1/video/insert")
  3. void insert(@RequestBody Video video);

订单服务Controller中增加方法

  1. //此处为了方便测试,是get请求
  2. @GetMapping("/insert")
  3. public void insert(){
  4. //此处为了测试方便,直接查询了一个视频
  5. Video video = orderService.findById(40);
  6. //远程调用
  7. orderService.insert(video);
  8. }

启动订单服务和视频服务,进行测试

  1. http://localhost:8000/api/v1/video_order/insert