前言
问题
在编写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 {
}