OpenFeign是Netflix 开发的声明式、模板化的HTTP请求客户端。可以更加便捷、优雅的调用http api
OpenFeign是会根据带有注解的函数信息构建出网络请求的模板,在发送网络请求之前,OpenFeign会将函数的参数值设置到这些请求模板中。
feign主要是构建微服务消费端。只要使用OpenFeign提供的注解修饰定义网络请求的接口类,就可以使用该皆苦的实例发送RESTful的网络请求。还可以集成Ribbon和Hystrix,提供负载均衡和断路器。
英文表意为 “假装,伪装,变形”,是一个http请求调用的轻量级框架,可以以java接口注解的方式调用Http请求,而不用像java中通过封装HTTP请求报文的方式直接调用。通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数在应用到请求上,进化转化为真正的请求,这种请求相对而言比较直观。Feign封装了HTTP调用流程,面向接口编程。
Feign本身不支持Spring MVC的注解,他有一套自己的注解
OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequestMapping等等。
OpenFeign的@FeignClient 可以解析Spring MVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
准备
先搭建一个eureka来供这些服务注册
引入依赖 Eureka管理端依赖 spring-cloud-starter-netflix-eureka-server
代码如下:
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
在Eurekaserver2Application加上@EnableEurekaServer注解,说明这个一个管理端
在工程的配置文件application.yaml文件,指定服务名为eurekaServer,主机名为eureka2.com,端口号为:7902
#Tomcat的端口
server:
port: 7902
eureka:
instance:
hostname: eureka2.com
spring:
application:
name: eurekaServer
先创建一个user-provider 项目,用来写接口,供调用方调用,就跟我们普通的SpringMVC写Controller 对外暴露接口差不多
引入,Eureka的客户端依赖spring-cloud-starter-netflix-eureka-client、Web依赖spring-boot-starter-web,代码如下:
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
在工程的配置文件application.yaml文件,指定服务提供方的服务名为user-provider,端口号为8003,服务注册地址为http://eureka2.com:7902/eureka/ ,代码如下:
server:
port: 8003
spring:
application:
name: user-provider
#设置服务注册中心的URL,用于client和server端交流
eureka:
client:
service-url:
defaultZone: http://eureka2.com:7902/eureka/
创建UserController类,随便提供一个测试的接口
package com.wan.userprovider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Auther: wan
* @Date: 2021/2/24 11:00
* @Description: com.wan.userprovider.controller
* @version: 1.0
*/
@RestController
public class UserController {
//无参get方法
@GetMapping("/getWan")
public String getWan(){
return "Hi wan 调用方式为:get!!";
}
//带参get方法
@GetMapping("/getWanParams")
public String getWanParams(String name){
return "Hello !! 调用方式为:get ,参数为:"+name;
}
//无参post方法
@PostMapping("/postWan")
public String postWan(){
return "Hi wan 调用方式为:post!!";
}
//带参post方法
@PostMapping("/postWanParams")
public String postWanParams(String name){
return "Hi wan 调用方式为:post,参数为:"+name;
}
}
创建user-consumer项目使用Feign 来调用服务提供方的接口
引入,Eureka的客户端依赖spring-cloud-starter-netflix-eureka-client、Web依赖spring-boot-starter-web,OpenFeign的依赖spring-cloud-starter-openfeign
有些工具只有openfeign没有feign,都区别不大。代码如下:
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
io.github.openfeign
feign-httpclient
还需要在入口application里面配置一下
在UserConsumerApplication类中加入@EnableFeignClients 注解
在工程的配置文件application.yaml文件,指定服务调用方的服务名为user-consumer,端口号为8004,服务注册地址为http://eureka2.com:7902/eureka/ ,代码如下:
server:
port: 8004
spring:
application:
name: user-consumer
#设置服务注册中心的URL,用于client和server端交流
eureka:
client:
service-url:
defaultZone: http://eureka2.com:7902/eureka/
在创建一个UserAPIService 接口类用来调用远程服务的接口
用Feign访问服务名称可以有两种写法
1. 下面这种方式带url的为直接访问,就是不通过eureka,直接访问服务,这就和我们平常调用接口差不多
@FeignClient(name = "wanFeign",url = "http://localhost:8003")
2. 第二种方式为根据服务名称访问,他中间是会走eureka的,通过服务名称去eureka服务列表中去找,name就是服务提供方的服务名称,
@FeignClient(name = "user-provider")
然后在定义的接口上写上映射,映射地址名称就是你需要调用的服务接口名称
/*
@FeignClient(name = "wanFeign",url = "http://localhost:8003")
如果结合eureka ,在FeignClient 注解中就可以不用写url,直接name指定服务名称就可以直接调用了
*/
@FeignClient(name = "user-provider")
public interface UserApi2Service {
@GetMapping("/getWan")
public String getWan();
@GetMapping("/getWanParams")
public String getWanParams(@RequestParam("name")String name);
@PostMapping("/postWan")
public String postWan();
@PostMapping("/postWanParams")
public String postWanParams(@RequestParam("name")String name);
}
接下来我们在写一个MainController,我就不解释了,直接上代码了
@RestController
public class MainController {
//服务直连,不通过eureka,直接进行请求
@Autowired
UserApiService userApiService;
//通过eureka服务名称请求
@Autowired
UserApi2Service userApi2Service;
//服务直连,不通过eureka,直接进行请求
@GetMapping("/getWan")
public String getWan(){
return userApiService.getWan();
}
//通过eureka服务名称请求-
@GetMapping("/getWan2")
public String getWan2(){
return userApi2Service.getWan();
}
//通过eureka服务名称请求-带参请求
@GetMapping("/getWanParams")
public String getWanParams(){
String name="Hi!! wan";
return userApi2Service.getWanParams(name);
}
//通过eureka服务名称请求-post无参请求
@GetMapping("/postWan")
public String postWan(){
return userApi2Service.postWan();
}
//通过eureka服务名称请求-post带参请求
@GetMapping("/postWanParams")
public String postWanParams(){
String name="Hi!! wan";
return userApi2Service.postWanParams(name);
}
}
这样我们一个简单的user-consumer(服务调用方),user-provider(服务提供方) 就创建好了
下面我们就来测试一下
把项目都启动起来
先访问注册中心地址,看看服务都注册上去没,http://localhost:7902/
发现里面有两个服务,一个是我们写的服务调用方,一个是我们写的服务提供方,说明没问题
接下来我们用请求服务调用方用Feign去调服务提供方的接口,服务调用方的端口我们配置的是8004,http://localhost:8004/getWan
可以访问成功,说明我们用Feign去调,成功了,没啥问题,接下来几个我就不一一去请求了,有兴趣的可以去试一试。
有疑问的小伙伴欢迎留言!