Spring Cloud : OpenFeign(远程调用)
RestTemplate虽然比直接用HTTPClient简单的多,但是还是存在着许多的问题,比如url拼接麻烦,容易出错,并且可读性很差
public OrderDetail selectOrderById(Integer orderId){OrderDetail orderDetail = orderMapper.selectOrderById(orderId);String url="http://product-service/product/"+orderDetail.getProductId();ProductDetail productDetail = restTemplate.getForObject(url, ProductDetail.class);orderDetail.setProductDetail(productDetail);return orderDetail;}
OpenFeign
微服务之间的通信,通常有RPC和HTTP,在SpringCloud中默认使用HTTP来进行微服务的通信,最常用的两种形式:RestTemplate和OpenFeign
OpenFeign是⼀个声明式的WebService客⼾端.它让微服务之间的调⽤变得更简单,类似controller 调⽤service, 只需要创建⼀个接⼝,然后添加注解即可使⽤OpenFeign
OpenFeign的使用
引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
添加注解@EnableFeignClients
用来开启OpenFeign的功能
@EnableFeignClients
@SpringBootApplication
@MapperScan("org.example1.mapper")
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class,args);}
}
写一个关于OpenFeign的客⼾端
用SpringMvc的注解进行调用
@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {@RequestMapping("/{productId}")ProductDetail selectProductById(@RequestParam("productId") Integer productId);@RequestMapping("/p1")String p1(@RequestParam("id") Integer id);@RequestMapping("/p2")String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);@RequestMapping("/p3")String p3(@SpringQueryMap ProductDetail productDetail);@RequestMapping("/p4")String p4(@RequestBody ProductDetail productDetail);
}
远程调用
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate ProductApi productApi;public OrderDetail selectOrderById(Integer orderId){OrderDetail orderDetail = orderMapper.selectOrderById(orderId);
ProductDetail.class);ProductDetail productDetail = productApi.selectProductById(orderDetail.getProductId());orderDetail.setProductDetail(productDetail);return orderDetail;}
}
OpenFeign关于参数的传递
包括一个参数,两个参数,传递对象,传递Json
首先我们在product-service中提供几个接口方法
@RestController
@RequestMapping("/product")
public class ProductController {@Autowiredprivate ProductService productService;@RequestMapping("p1")private String p1(Integer id){return "参数传递:"+id;}@RequestMapping("p2")private String p2(Integer id,String name){return "参数传递,id:"+id+"name"+name;}@RequestMapping("p3")private String p3(ProductDetail productDetail){return "传递对象"+productDetail;}@RequestMapping("p4")private String p4(@RequestBody ProductDetail productDetail){return "接受Json对象"+productDetail;}}
在Feign客户端
@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {@RequestMapping("/p1")String p1(@RequestParam("id") Integer id);@RequestMapping("/p2")String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);@RequestMapping("/p3")String p3(@SpringQueryMap ProductDetail productDetail);@RequestMapping("/p4")String p4(@RequestBody ProductDetail productDetail);
}
最后通过order-service服务调用
@RequestMapping("/feign")
@RestController
public class FeignController {@Autowiredprivate ProductApi productApi;@RequestMapping("/o1")public String o1(Integer id){return productApi.p1(id);}@RequestMapping("/o2")public String o2(Integer id,String name){return productApi.p2(id,name);}@RequestMapping("/o3")public ProductDetail o3(){ProductDetail productDetail=new ProductDetail();productApi.p3(productDetail);productDetail.setId(1);productDetail.setProductName("zhangsan");return productDetail;}@RequestMapping("/o4")public ProductDetail o4(){ProductDetail productDetail=new ProductDetail();productApi.p3(productDetail);productDetail.setId(1);productDetail.setProductName("zhangsan");return productDetail;}}
我们可以来测试一下
传递一个参数的
传递两个参数的
传递对象的
传递Json对象的
Feign 继承⽅式
Feign支持继承的方式,我们可以把一些常见的操作封装到接口中
创建一个新的服务product-api
将Feign客户端写在这个服务中,这样在调用的时候就不用再重写了
将Feign继承product-api
@FeignClient(value = "product-service", path = "/product")
public interface ProductApi extends org.example.ProductApi {}
注:在product-api服务中记得写入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
在写好product-api服务后,将其install到本地
然后再重新测试一下
Feign 抽取⽅式
就是直接将Feign写成一个独立的模块,将product-service中的product-api接口删除
然后重新启动程序,发现报错了
我们需要再启动类中添加
@EnableFeignClients(clients = {ProductApi.class})
@SpringBootApplication
@MapperScan("org.example1.mapper")
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class,args);}
}
标明需要加载的Feign客⼾端
注:在部署服务的时候需要修改pom文件
希望对大家有所帮助!!!!!