文章目录
- 问题引入
- 一、继承的方式
- 1. 建立独立的Moudle服务
- 2. 服务调用方继承jar包中的接口
- 3. 直接注入继承后的接口进行使用
- 二、抽取的方式
- 1. 建立独立的Moudle服务
- 2.服务调用方依赖注入
问题引入
openfeign接口的实现和服务提供方的controller非常相似,例如:
- 服务端
@RequestMapping("/product")
public class ProductController implements ProductInterface {@Autowiredprivate ProductService productService;@RequestMapping("/{productId}")public ProductInfo getProductInfoById(@PathVariable("productId") Integer productId){log.error("开始运行product-service");return productService.selectProductById(productId);}@RequestMapping("/p1")public String p1(Integer id){return "product-service "+id;}@RequestMapping("/p2")public String p2(Integer id,String name){return id+" "+name;}@RequestMapping("/p3")public String p3(ProductInfo productInfo){return productInfo.toString();}//返回json格式@RequestMapping("/p4")public String p4(@RequestBody ProductInfo productInfo){return productInfo.toString();}
}
- openfeign接口
@RequestMapping("/feign")
@RestController
public class FeignController {@Autowiredprivate ProductApi productApi;//@RequestParam不可以省略@RequestMapping("/o1")public String o1(Integer id){return productApi.p1(id);}//@RequestParam不可以省略@RequestMapping("/o2")public String o2(Integer id,String name){return productApi.p2(id,name);}@RequestMapping("/o3")public String o3(){ProductInfo productInfo = new ProductInfo();// 使用 setter 方法设置字段productInfo.setId(101);productInfo.setProductName("华为Mate60");productInfo.setProductPrice(6999);productInfo.setState(1);return productApi.p3(productInfo);}@RequestMapping("/o4")public String o4(){ProductInfo productInfo = new ProductInfo();// 使用 setter 方法设置字段productInfo.setId(101);productInfo.setProductName("华为Mate60");productInfo.setProductPrice(6999);productInfo.setState(1);return productApi.p4(productInfo);}
}
如果有多个服务调用方,我们就需要写多次这种重复的代码,比较麻烦。
那么我们希望能不能有一个简介的写法去实现呢?
答案是有的,主要有两种方式:
- 继承的方式
- 抽取的方式
一、继承的方式
1. 建立独立的Moudle服务
注意:product-api也是一个独立的服务,所以也需要引入spring-boot和spring-cloud-openfeign相关依赖。
把Openfeign接口的方法统一放到product-api中:
public interface ProductInterface {@RequestMapping("/{productId}")ProductInfo getProductInfoById(@PathVariable("productId") Integer productId);//@RequestParam不可以省略@RequestMapping("/p1")String p1(@RequestParam("id") Integer id);@RequestMapping("/p2")String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);//@SpringQueryMap把传过来的Java对象的字段转换成url格式@RequestMapping("/p3")String p3(@SpringQueryMap ProductInfo productInfo);//返回json格式@RequestMapping("/p4")String p4(@RequestBody ProductInfo productInfo);
}
这些接口的方法中可能涉及别的服务的实体类,因此我们需要导入其他服务中的实体类。
创建好这个服务后,对这个服务进行打成jar包:
2. 服务调用方继承jar包中的接口
@FeignClient(value = "product-service",path="/product")//指定需要访问的服务的名称 application-name
public interface ProductApi extends ProductInterface {
}
注意需要导入刚才打好的jar包依赖:
<dependency><groupId>com.hyy</groupId><artifactId>product-api</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency>
3. 直接注入继承后的接口进行使用
public class FeignController {@Autowiredprivate ProductApi productApi;//@RequestParam不可以省略@RequestMapping("/o1")public String o1(Integer id){return productApi.p1(id);}
}
这就是继承的方式实现openfeign,我们不需要对每一个服务调用方写方法的实现了,简化了编写流程,这种继承的方式是spring官方推荐的。
二、抽取的方式
抽取的方式,把解耦合做的更彻底,把opnfeign远程远程调用的功能全部统一放到一个服务中,其他服务调用方使用它提供的jar包即可,相比于继承的方式,抽取的方式连继承都不用写,直接依赖注入即可。
1. 建立独立的Moudle服务
同样地,这里的product-api也是一个独立的服务,所以也需要引入spring-boot和spring-cloud-openfeign相关依赖。
把Openfeign接口的方法统一放到product-api中:
//因为解耦合彻底,这里把远程调用涉及的指定服务也需要加上,避免在服务调用方重新配置
@FeignClient(value = "product-service",path="/product")//指定需要访问的服务的名称 application-name
public interface ProductInterface {@RequestMapping("/{productId}")ProductInfo getProductInfoById(@PathVariable("productId") Integer productId);//@RequestParam不可以省略@RequestMapping("/p1")String p1(@RequestParam("id") Integer id);@RequestMapping("/p2")String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);//@SpringQueryMap把传过来的Java对象的字段转换成url格式@RequestMapping("/p3")String p3(@SpringQueryMap ProductInfo productInfo);//返回json格式@RequestMapping("/p4")String p4(@RequestBody ProductInfo productInfo);
}
同样地,某些其他服务的实体类也需要我们导入,比如ProductInfo等。
值得注意的是:
如果服务调用方的实体类与openfeign接口的实体类路径不同,我们需要统一使用openfeign接口的实体类地址
创建好这个服务后,对这个服务进行打成jar包:
2.服务调用方依赖注入
//下面是spring mvc的程序
@RequestMapping("/feign")
@RestController
public class FeignController {//注入刚才打好的jar包(注意也需要导入jar包依赖)@Autowiredprivate ProductApi productApi;//依赖注入完之后,就可以直接使用远程调用了//@RequestParam不可以省略@RequestMapping("/o1")public String o1(Integer id){return productApi.p1(id);}
个人认为抽取的方式会跟加好用,因为它解耦合更彻底,完全可以看作是一个独立的模块,尽管继承的方式是官方推荐的。