一、声明式的服务
Feign是一个声明性的Web服务客户端。它使编写Web服务客户端变得更容易。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。另外它还集成了Ribbon,Eureka及Hystrix,所以feign也能实现了负载均衡,服务注册,断路器功能。(感觉很棒,集成这么多也就意味着pom.xml文件夹里需要依赖的文件变少了)
既然叫声明式的服务调用,那么,作者想,只需要把接口列出来,然后对外声称,这些接口是我要发送的,不需要多余的代码,可能仅仅就提供一个标记。就可以完成整个功能!
二、搭建一个Feign的例子并说明
为了扩展多参数的接口,我们首先在服务端的Controller类中加入处理客户端的接口处理类,代码如下(只是部分):
@RequestMapping(value="/hello")
public String index() {
return "hello server1";
}
@RequestMapping(value="/hello1",method = RequestMethod.GET)
public String index1(@RequestParam String name) {
return "Hello"+name;
}
@RequestMapping(value="/hello2",method=RequestMethod.GET)
public User index2(@RequestHeader Long id,@RequestHeader String name) {
return new User(id,name);
}
@RequestMapping(value="/hello3",method=RequestMethod.POST)
public String index3(@RequestBody User user) {
return "Hello "+ user.getId()+", "+user.getName();
}
可参考之前服务端的例子,可参考:https://blog.csdn.net/notMoonHeart/article/details/84954217
增加好服务之后,我们开始搭建Fegin。
1.创建一个Spring Boot工程,命名为:feign-consumer,并更改pom.xml文件,引入所需要的包。(因为Feign集成了很多功能的缘故,所以引用的依赖会特比少),代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
2.创建声明接口的接口,命名为HelloService.java,代码如下:
package com.example.demo.web;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient("hello-service")
public interface HelloService {
@RequestMapping(value="/hello", method = RequestMethod.GET)
String hello();
@RequestMapping(value = "/hello1", method= RequestMethod.GET)
String hello(@RequestParam("name") String name) ;
@RequestMapping(value = "/hello2", method= RequestMethod.GET)
User hello(@RequestHeader("id") Long id, @RequestHeader("name") String name);
@RequestMapping(value = "/hello3", method= RequestMethod.POST)
String hello(@RequestBody User user);
}
分析:上面的代码就是声明式的服务,在接口中声明,然后只需要注入实例,调用声明的方法即可发送请求,不需要再写之前的getForEntity。。。等方法来发送请求。所以这里一切的声明,都是通过@FeignClient注解实现的。
3.创建Controller类,发送请求,命名:HelloContronller.java 代码如下:
package com.example.demo.web;
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.RestController;
@RestController
public class HelloContronller {
@Autowired
HelloService helloService;
@RequestMapping(value="/feign-consumer", method=RequestMethod.GET)
public String helloConsumer() {
return helloService.hello();
}
@RequestMapping(value="/feign-consumer1", method=RequestMethod.GET)
public String helloConsumer1() {
StringBuilder sb = new StringBuilder();
sb.append(helloService.hello()).append("---");
sb.append(helloService.hello("nana")).append("---");
sb.append(helloService.hello(10L, "nana")).append("---");
sb.append(helloService.hello(new User(11L, "nana2")));
return sb.toString();
}
}
4.启动类增加注解,@SpringBootApplication,@EnableFeignClients,@EnableDiscoveryClient(这里就不沾代码了)
5.修改配置文件application.properties,代码如下:
server.port=8090
spring.application.name=feign-consumer
eureka.client.service-url.defaultZone=http://localhost:8088/eureka/eureka
6.启动eureka和2个服务工程,然后再启动feign-consumer,访问http://localhost:8090/feign-consumer和http://localhost:8090/feign-consumer1,会发现feign是实现负载均衡功能的。
三、feign实现fallback
feign既然集成了Hystrix,并且声明类的服务把发送请求封装成了接口形式,那么要实现断路器功能,它应该怎么实现呢?下面通例子来看看。
1.开启Hystrix,feign虽然集成了Hystrix,但是默认情况下是关闭的(作者被这个坑惨了),修改application.properties配置文件,增加如下代码:
feign.hystrix.enabled=true
2.开启之后,只需要写一个实现声明接口的类,再配置属性就可以开启fallback功能了。创建实现声明类,命名为HelloServiceFillback.java,代码如下:
package com.example.demo.web;
public class HelloServiceFillback implements HelloService{
@Override
public String hello(User user) {
return user.toString()+" error";
}
@Override
public User hello(Long id, String name) {
return new User(99L, "error");
}
@Override
public String hello(String name) {
return name+": error";
}
@Override
public String hello() {
return "error";
}
}
3.配置fallback属性,在声明接口中,修改配置属性,如下:
@FeignClient(name="hello-service",fallback=HelloServiceFillback.class)
public interface HelloService {
....
}
4.在启动类中要用Spring bean声明fallback实现类的实例,在FeignConsumerApplication.java 增加如下代码:
@Bean
public HelloServiceFillback fallback() {
return new HelloServiceFillback();
}
5.然后启动项目,帮刚才启动的server服务类全部粗暴的干掉,访问http://localhost:8090/feign-consumer1,会出现自定义的返回信息,如下: