文章目录
- 问题引入
- 一、继承的方式
- 1. 建立独立的Moudle服务
- 2. 服务调用方继承jar包中的接口
- 3. 直接注入继承后的接口进行使用
- 二、抽取的方式
- 1. 建立独立的Moudle服务
- 2.服务调用方依赖注入
问题引入
openfeign接口的实现和服务提供方的controller非常相似,例如:
- 服务端
@RequestMapping("/product")
public class ProductController implements ProductInterface {
@Autowired
private 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 {
@Autowired
private 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 {
@Autowired
private 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包依赖)
@Autowired
private ProductApi productApi;
//依赖注入完之后,就可以直接使用远程调用了
//@RequestParam不可以省略
@RequestMapping("/o1")
public String o1(Integer id){
return productApi.p1(id);
}
个人认为抽取的方式会跟加好用,因为它解耦合更彻底,完全可以看作是一个独立的模块,尽管继承的方式是官方推荐的。