是什么
是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单,使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
只需要创建一个接口,然后在上面添加注解即可。
干什么
使编写Java Http客户端变得更容易。
前面使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多次调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。
Feign集成了Ribbon
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方式,优雅而简单的实现了服务调用。
案例
1. 创建micoservicecloud-consumer-dept-feign的maven工程
2. 在pom.xml中添加依赖
1<dependencies> 2 <dependency> 3 <groupId>com.minn.springcloud</groupId> 4 <artifactId>micoservicecloud-api</artifactId> 5 <version>${project.version}</version> 6 </dependency> 7 <dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-web</artifactId> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework</groupId> 13 <artifactId>springloaded</artifactId> 14 </dependency> 15 <dependency> 16 <groupId>org.springframework.boot</groupId> 17 <artifactId>spring-boot-devtools</artifactId> 18 </dependency> 19 <!-- Ribbon相关 --> 20 <dependency> 21 <groupId>org.springframework.cloud</groupId> 22 <artifactId>spring-cloud-starter-eureka</artifactId> 23 </dependency> 24 <dependency> 25 <groupId>org.springframework.cloud</groupId> 26 <artifactId>spring-cloud-starter-ribbon</artifactId> 27 </dependency> 28 <dependency> 29 <groupId>org.springframework.cloud</groupId> 30 <artifactId>spring-cloud-starter-config</artifactId> 31 </dependency> 32 <dependency> 33 <groupId>org.springframework.cloud</groupId> 34 <artifactId>spring-cloud-starter-feign</artifactId> 35 </dependency> 36</dependencies>
3. 在公共的maven工程micoservicecloud-api中添加公共接口类DeptClientService
1package com.minn.springcloud; 2 3import com.minn.springcloud.entities.Dept; 4import org.springframework.cloud.netflix.feign.FeignClient; 5import org.springframework.web.bind.annotation.PathVariable; 6import org.springframework.web.bind.annotation.RequestMapping; 7import org.springframework.web.bind.annotation.RequestMethod; 8import java.util.List; 9 10@FeignClient(value = "MICOSERVICECLOUD-DEPT") 11public interface DeptClientService { 12 @RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET) 13 public Dept get(@PathVariable("id") long id); 14 15 @RequestMapping(value = "/dept/list",method = RequestMethod.GET) 16 public List<Dept> list(); 17 18 @RequestMapping(value = "/detp/add",method = RequestMethod.POST) 19 public boolean add(Dept dept); 20}
4. 公共的maven工程micoservicecloud-api中pom.xml中添加feign的依赖:
1<dependency> 2 <groupId>org.springframework.cloud</groupId> 3 <artifactId>spring-cloud-starter-feign</artifactId> 4</dependency>
5. micoservicecloud-consumer-dept-feign工程添加application.yml
1server: 2 port: 80 3eureka: 4 client: 5 service-url: 6 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 7 register-with-eureka: false
6. micoservicecloud-consumer-dept-feign工程添加controller类调用公共工程中的接口类DeptClientService
1package com.minn.springcloud.controller; 2 3import com.minn.springcloud.DeptClientService; 4import com.minn.springcloud.entities.Dept; 5import org.springframework.beans.factory.annotation.Autowired; 6import org.springframework.web.bind.annotation.PathVariable; 7import org.springframework.web.bind.annotation.RequestMapping; 8import org.springframework.web.bind.annotation.RestController; 9import java.util.List; 10 11@RestController 12public class DeptController_Consumer { 13 @Autowired 14 private DeptClientService deptClientService; 15 16 @RequestMapping(value = "/consumer/dept/add") 17 public boolean add(Dept dept){ 18 return deptClientService.add(dept); 19 } 20 21 @RequestMapping(value = "/consumer/dept/get/{id}") 22 public Dept get(@PathVariable("id") Long id){ 23 return deptClientService.get(id); 24 } 25 26 @RequestMapping(value = "/consumer/dept/list") 27 public List<Dept> list(){ 28 return deptClientService.list(); 29 } 30}
7. micoservicecloud-consumer-dept-feign工程添加启动类
1package com.minn.springcloud; 2 3import org.springframework.boot.SpringApplication; 4import org.springframework.boot.autoconfigure.SpringBootApplication; 5import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6import org.springframework.cloud.netflix.feign.EnableFeignClients; 7 8@SpringBootApplication 9@EnableEurekaClient 10@EnableFeignClients(basePackages = {"com.minn.springcloud"}) 11public class DeptConsumer80_Feign_App { 12 public static void main(String[] args) { 13 SpringApplication.run(DeptConsumer80_Feign_App.class,args); 14 } 15}
小总结
Feign通过接口的方法调用Rest服务(之前是Ribbon + RestTemplate)
该请求发送给Eureka服务器(http://MICOSERVICECLOUD-DEPT/dept/list),通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。