一、Feign的简介
Feign是一个声明式 WebService 客户端,使用Feign能够让编写Web Service 客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可插拔式的编码器和解码器。
Spring Cloud 对 Fiegn 进行了封装,使其支持了Spring MVC 标准注解和HttpMessageConverts。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
前面使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法,但是在实际的开发中,由于对服务依赖的调用可能不止一处。往往一个接口会被多处调用,所以通常会对每个微服务自行封装一些客户端类来包装依赖服务的调用,所以Feign在此基础上做了进一步封装,有他来帮助我们自定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置他(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成服务提供放的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。
二、工程配置
1、在 microservicecloud-api 工程增加pom依赖和代码:
(1)pom.xml文件中添加feign的jar包:spring-cloud-starter-feign
<!-- feign相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
(2)新建DeptClientService接口并且添加@FeignClient注解
@FeignClient(value = "microservicecloud-dept")
public interface DeptClientService
{
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept);
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id);
@RequestMapping(value = "/dept/get/list", method = RequestMethod.GET)
public List<Dept> list();
}
说明:
@FeignClient的value值指明对哪个微服务进行负载均衡;
@RequestMapping 是Spring提供的注解,这里可以直接使用以前使用SpringMVC时用过的各种注解,唯一不同的是,这里只是把注解用在了接口上。
2、新建一个消费者项目(Feign):microservicecloud-consumer-dept-feign
(1)添加pom.xml中的依赖
<dependencies>
<dependency><!-- 自己定义的api -->
<groupId>com.yufeng.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
(2)在主启动类中增加 @EnableFeignClients 注解
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DeptConsumer80_Feign_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptConsumer80_Feign_App.class, args);
}
}
在主启动类中增加 @EnableFeignClients 注解之后,在Controller中使用 @Autowired 注解导入 DeptClientService 时候才不会报错;
(3)在controller包下增加 DeptController ,使用@Autowired直接注入上面定义的 FeignConsumerService接口对应的实例
@RestController
public class DeptController
{
@Autowired
private DeptClientService deptClientService;
@RequestMapping(value = "/consumer/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id)
{
return deptClientService.get(id);
}
@RequestMapping(value = "/consumer/dept/get/list", method = RequestMethod.GET)
public List<Dept> list()
{
return deptClientService.list();
}
}
(4)结果验证:启动eureka集群,启动3个生产者服务,启动本服务;
在浏览器中打开:http://localhost/consumer/dept/get/1,可以看到轮询调用了3个生产者服务;
importcom.yufeng.springcloud.entities.Dept;
import org.springframework.cloud.netflix.feign.FeignClient;
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.RequestMethod;
import java.util.List;
/**
* Created by Administrator on 2019/6/11.
*/
@FeignClient(value = "microservicecloud-dept")
public interface FeignConsumerService
{
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept);
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id);
@RequestMapping(value = "/dept/get/list", method = RequestMethod.GET)
public List<Dept> list();
}
最新评论