一、简单介绍
OpenFeign 是⼀个声明式的 Web Service 客户端. 它让微服务之间的调用变得更简单,类似controller 调用 service, 只需要创建⼀个接口,然后添加注解即可使用 OpenFeign.
二、使用方法
这里的项目是在实现 nacos 基础上实现的(可以看之前nacos的用法)
1、在服务消费者(order-service)pom 文件中引入 OpenFeign 依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>2、添加注解
在服务消费者 order-service的启动类添加注解 @EnableFeignClients ,开启OpenFeign的功能.
package com.linzhixin.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients @SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }3、编写 OpenFeign 的客户端
pimport org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @FeignClient(value = "product-service", path = "/product") public interface ProductApi { @RequestMapping("/{productId}") ProductInfo getProductById(@PathVariable("productId") Integer productId); }4、远程调用
@Autowired private ProductApi productApi; public OrderInfo selectOrderById(Integer orderId) { OrderInfo orderInfo = orderMapper.selectOrderById(orderId); ProductInfo productInfo = productApi.getProductById(orderInfo.getProductId()); orderInfo.setProductInfo(productInfo); return orderInfo; }5、访问接口测试
三、最佳使用方法(使用方法的改进) -- Feign 继承方式
参考文档:https://docs.spring.io/spring-cloud-openfeign/reference/spring-cloud-openfeign.html#spring-cloud-feign-inheritance
1、创建一个 Module(接口可以放在⼀个公共的Jar包里, 供服务提供方和服务消费方使用)
这里包含 productInfo 的对象,可以把 order-service 和 product-service 里面的 productInfo 删了,通过引入打包的 product-api 来映入 product-api 中的 productInfo
2、引入依赖
<dependencies> <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> </dependencies>
3、编写接口
package com.linzhixin.product.api; import com.linzhixin.product.model.ProductInfo; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; public interface ProductInterface { @RequestMapping("/{productId}") ProductInfo getProductById(@PathVariable("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 ProductInfo productInfo); @RequestMapping("/p4") String p4(@RequestBody ProductInfo productInfo); }4、打 Jar 包
通过右侧 maven 打 包
5、服务提供方实现接口ProductInterface
package com.linzhixin.product.controller; import com.linzhixin.product.api.ProductInterface; import com.linzhixin.product.model.ProductInfo; import com.linzhixin.product.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/product") @RestController public class ProductController implements ProductInterface { @Autowired private ProductService productService; @RequestMapping("/{productId}") public ProductInfo getProductById(@PathVariable("productId") Integer productId) { System.out.println("收到请求,Id:"+productId); return productService.selectProductById(productId); } @RequestMapping("/p1") public String p1(Integer id){ return "p1接收到参数:"+id; } @RequestMapping("/p2") public String p2(Integer id,String name){ return "p2接收到参数,id:"+id +",name:"+name; } @RequestMapping("/p3") public String p3(ProductInfo productInfo){ return "接收到对象, productInfo:"+productInfo; } @RequestMapping("/p4") public String p4(@RequestBody ProductInfo productInfo){ return "接收到对象, productInfo:"+productInfo; } }6、服务消费方继承 ProductInterface 接口
package com.linzhixin.order.api; import com.linzhixin.product.api.ProductInterface; import org.springframework.cloud.openfeign.FeignClient; @FeignClient(value = "product-service", path = "/product") public interface ProductApi extends ProductInterface { }7、测试
四、最佳使用方法(使用方法的改进) -- Feign 抽取方式
这里还是在二、使用方法上改进
1、创建一个 product-api module
这里包含 productInfo 的对象,可以把 order-service 里面的 productInfo 删了,通过引入打包的 product-api 来映入 product-api 中的 productInfo
2、为 product-api 引入依赖
<dependencies> <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> </dependencies>
3、编写 ProductApi
package com.linzhixin.product.api; import com.linzhixin.product.model.ProductInfo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(value = "product-service", path = "/product") public interface ProductApi { @RequestMapping("/{productId}") ProductInfo getProductById(@PathVariable("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 ProductInfo productInfo); @RequestMapping("/p4") String p4(@RequestBody ProductInfo productInfo); }4、通过Maven 打 product-api module 的 jar 包
5、服务消费方使用 product-api
1、删除 order-service 里面的 Product-Api, ProductInfo
2、引入依赖
<dependency> <groupId>com.linzhixin</groupId> <artifactId>product-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
注意要修改报错的地方(改路径)
3、指定需要加载的 Feign 客户端
package com.linzhixin.order; import com.linzhixin.product.api.ProductApi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients(clients = {ProductApi.class}) @SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }6、测试