20、Feign接口继承特性

前言

问题

在编写Feign 接口时,我们需要写注解来声明请求的路径、参数。而在被调用方,这些是已经声明好了的,重复在写一次,很容易出错,而且也有冗余。
 

Feign接口继承特性

在之前分析加载方法元数据的文档中,有提到在获取方法元数据是也会获取父接口中方法,也就是说父类接口的方法也会被加载为元数据,用于构建请求模板。
 
那么通过这种方式,我们可以定义好一个接口,让服务提供方实现这个接口,编写业务逻辑,让调用方编写Feign 接口的时候,直接继承这个就可以了,这样就能轻松实现Feign 远程调用。

改造案例

1. 定义统一接口

首先使用之前的案例,在order-api包中,添加POJO 类、Feign API接口,别人想通过Feign 调用这个服务时,直接引入这个包就可以了。
 
编写一个Feign 接口,声明Spring MVC访问方式,注意这个接口必须是顶层接口。

@RequestMapping("/order")
public interface OrderFeignApi {

    @GetMapping("insert")
    public List<Order> insertOrder(@RequestParam("accountId") Long accountId, @RequestParam("commodityCode") String commodityCode, @RequestParam("count") Long count, @RequestParam("money") Long money);

    @PostMapping("/post")
    public Order post(Order order);

    @GetMapping("id/{id}")
    public List<Order> id(@PathVariable("id") String id);
}

2. 提供方实现接口

order-service中,实现上述接口, 编写实际的处理逻辑

@RestController
public class OrderTblController implements OrderFeignApi {

    @Value("${server.port}")
    String port;

    @Override
    public List<Order> insertOrder(Long accountId, String commodityCode, Long count, Long money) {

        // 模拟给当前账户下单
        List<Order> list = new ArrayList<>();
        for (long i = 0L; i < 10000L; i++) {

            Order order = new Order();
            order.setAccountId(accountId);
            order.setCommodityCode(commodityCode);
            order.setCount(count);
            order.setMoney(1L);
            order.setPort(port);
            list.add(order);
        }
        return list;
    }

    @Override
    public Order post(Order order) {

        return order;
    }

    @Override
    public List<Order> id(String id) {

        System.out.println(id);
        return null;
    }
}

3. 消费者继承接口

在消费者中,如果要调用提供者的服务,只需要编写一个接口继承api 包中的接口,然后使用@FeignClient标注需要调用的服务名就可以了,这样就非常的方便,而且不容易出错。

@FeignClient(name = "order-service", configuration = {

     BBB.class}, fallbackFactory = OrderFeignFallbackFactory.class)
public interface OrderFeign extends OrderFeignApi {

}