Feign是从Netflix中分离出来的轻量级项目,能够在接口上添加注释,成为一个REST API 客户端,使得Java HTTP客户端编写更方便。FeignFeign的灵感来源于Retrofit、JAXRS-2.0和WebSocket。
Feign中对 Hystrix 有依赖关系。Feign只是一个便利的REST框架,简化调用,最后还是通过ribbon在注册服务器中找到服务实例,然后对请求进行分配。
你可以使用Jersey和CXF这些来写一个Rest或SOAP服务的Java客服端。你也可以直接使用Apache HttpClient来实现。但是 Feign 的目的是尽量的减少资源和代码来实现和 HTTP API 的连接。通过自定义的编码解码器以及错误处理,你可以编写任何基于文本的 HTTP API。
Feign 通过注解(Annotation)注入一个模板化请求进行工作。只需在发送之前关闭它,参数就可以被直接的运用到模板中。然而这也限制了Feign,只支持文本形式的API,它在响应请求等方面极大的简化了系统。同时,它也是十分容易进行单元测试的。
该实例启动一个eureka-server注册中心,然后启动两个server,端口分别是8762和8763,注册到eureka-server注册中心,然后使用feign进行声明式调用。项目结构如下图:
其中:
chapter3-eureka-server:Eureka服务注册中心
chapter3-service-hi:server服务(需要启动两个服务,端口分别为8762和8763)
chapter3-service-ribbon:使用RestTemplate+Ribbon实现负载均衡调用
chapter3-service-feign:使用Feign进行声明式负载均衡调用
项目中用到的其他Maven依赖这里不在赘述,下面只介绍引入Feign的依赖,如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
对于chapter3-eureka-server、chapter3-service-hi和chapter3-ribbo模块这里就不在一一创建,如果不会,可以参考前面的实例。这里主要介绍怎样创建chapter3-service-feign模块,具体步骤如下:
(1)修改application.yml配置文件
(2)添加maven依赖,<dependencies>标签代码如下:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
(3)编写Java代码,Java代码结构如下图:
ServiceFeignApplication.java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication //@EnableDiscoveryClient @EnableEurekaClient @EnableFeignClients public class ServiceFeignApplication { public static void main(String[] args) { SpringApplication.run(ServiceFeignApplication.class, args); } }
上面代码中,通过注解@EnableEurekaClient开启Eureka Client的功能(@EnableDiscoveryClient也能实现同样的功能),通过注解@EnableFeignClients开启Feign Client的功能。
SchedualServiceHi.java
import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; // service-hi 表示服务名称 @FeignClient(value = "service-hi") public interface SchedualServiceHi { // 映射请求 @RequestMapping(value = "/hi", method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name); }
上面代码中,实现一个简单的Feign Client,新建一个EurekaClientFeign 的接口,在接口上加@FeignClient 注解来声明一个 Feign Client,其中value为远程调用其他服务的服务名。在EurekaClientFeign接口内部有一个sayHiFromClientEureka()方法,该方法通过 Feign 来调用eureka-client 服务的“/hi”的API接口。
HiController.java
import com.forezp.service.SchedualServiceHi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HiController { @Autowired private SchedualServiceHi schedualServiceHi; @RequestMapping(value = "/hi",method = RequestMethod.GET) public String sayHi(@RequestParam String name){ return schedualServiceHi.sayHiFromClientOne(name); } }
上面代码中,@RestController注解表示这是一个REST Http服务,在sayHi()方法中通过SchedualServiceHi接口去调用chapter3-service-hi服务。
项目源码地址:
https://gitee.com/hxstrive/spring_learning/tree/master/spring_cloud/springcloud_learn1/chapter3