前言
前面消费者在调用生产者提供的服务的时候,是使用Ribbon+RestTemplate会http请求进行封住,形成一条模板化的方法,但是在实际开发中,对于服务的调用可能不止一处,往往一个接口会被好多次调用。如果我们每次调用都通过RestTemplate封装请求,这样会让代码不够灵活,比如当修改了请求的时候,将要修改每一处调用,那么能不能换一种服务调用的方式呢…下面老夫慢慢道来
一、什么是Feign
Feign
是一个声明式的web服务客户端。前面提到Ribbon+RestTemplate
直接调用http请求的方式太过生硬,feign
就其替代方案,它采用不同的方法来调用REST服务,方法是让开发人员先定义一个java接口,然后使用注解标注一下以映射Ribbon将要调用的Eureka服务。(这种效果类似dao的mapper 我们标注@mapper接口,之后就可以调用)。标注之后,即可以对服务提供方的接口进行绑定,简化了使用spring cloud Ribbon 自动服务调用客户端的开发量。
其目的就是使得编写java Http客户端更加简便,除了编写接口定义之外,开发人员不需要编写其他调用方法(接口+注解)
二、Feign客户端搭建
目标:
1、创建feign服务的接口
2、创建模块microservice_product_consumer80_feign
(1)修改microcloudservice-api
因为这个接口属于公共模块,所以我们把他放在microcloudservice-api
这个项目中
1、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2、声明接口+注解
创建一个类ProductClientService
,这也就是一个Feign
调用接口 然后通过@FeignClient
,指定我们需要调用的Eureka中哪一个服务。比如下面我们所配置的MICROSERVICE-PROVIDER
,这个也就是我们调用的目标服务
/**
* @author hao
* @create 2019-07-28 ${TIM}
* 定义feign接口 提供服务的调用
*/
@FeignClient(value = "MICROSERVICE-PROVIDER")
public interface ProductClientService {
@GetMapping("/product/list")
List<Product> list();
@GetMapping("/product/{id}")
Product get(@PathVariable(value = "id") Long id);
@PostMapping("/product")
boolean add(@RequestBody Product product);
}
创建完成之后,我们需要将该模块的修改更新到本地厂库,依次执行下面两个命令。
3、新建一个模块microservice_product_consumer80_feign
该模块作为服务的消费者,通过feign
客户端的形式,代用消费者提供的服务。创建过程同microservice_product_consumer80
。创建完成如下:
4、创建ProductController
@RestController
public class ConsumerController {
private static final String REST_URL_PREFIX = "http://localhost:8001/";
@Autowired
private ProductClientService productClientService;
@GetMapping("/consumer/product/list")
public List<Product> list(){
//restTemplate.getForObject(REST_URL_PREFIX+"product/list",List.class)使用url访问
return productClientService.list();
}
@GetMapping("/consumer/product/{id}")
public Product get(@PathVariable Long id){
return productClientService.get(id);
}
@RequestMapping("/consumer/product")
public boolean add(Product product){
return productClientService.add(product);
}
}
我们通过注入,我们在microcloudservice-api
声明的服务调用接口,然后通过Feign
接口的方式去调用服务。上面的代码是不是看起来更加舒服啊 简洁啊。符合我们的编程习惯,注入接口,面向接口编程。
5、在主配置类中添加Feign相关的注解
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients(value = {"com.kuake.service"})
public class ConsumerFeign80Application {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeign80Application.class,args);
}
}
@EnableFeignClients(value = {"com.kuake.service"})
这表明开启基于Feigin的客户端调用。然后指定接口所在的包。
6、开始测试
为了节约时间,我这里就不启动集群服务了,就启动一个Eureka集群服务,和一个服务的提供者,一个服务的消费者(也就是我们刚刚创建的Feign)。
启动成功之后浏览器输入http://localhost/consumer/product/list
[{"pid":1,"dbSource":"springcloud001","pname":"舒肤佳"},{"pid":2,"dbSource":"springcloud001","pname":"可口可乐"},{"pid":3,"dbSource":"springcloud001","pname":"百事可乐"},{"pid":4,"dbSource":"springcloud001","pname":"冰箱"},{"pid":5,"dbSource":"springcloud001","pname":"电视"},{"pid":6,"dbSource":"springcloud001","pname":"苹果"}]
能够正常访问,说明我们通过Feign
客户端请求成功啦。
小结:
Feign
的目的也就是让我们用一种更优雅的方式,发送REST请求,也更符合程序员的编程习惯,面向接口编程。