Feign实现服务间的调用(学习笔记)
前言:
Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
1. 加入Fegin依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 在启动类加上@EnableFeignClients注解,开启Feign
的功能
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //加上注解启用fegin功能
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
3.定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务比如在代码中调用了service-test服务的“/hi”接口,代码如下:
@FeignClient("service-test") //注解要指定服务名 _不能有下划线
public interface FeginHiClient {
//service-hi服务中名字为"hi"的接口
@GetMapping("/hi")
String sayHi();
}
注意事项:
- 接口上通过注解指定要调用的微服名称(不能有下划线)
- 接口中写具体的被调用的方法(参考被调用的微服controller类中的方法) 注:记得添加controller类上的路径
- 调用方通过@Autowired注入接口即可调用
- 注意启动顺序: 注册中心->被调用的微服->调用方微服
4.在controller层,对外暴露一个"getHi"
的API接口,通过上面定义的Feign客户端FeginHiClient来消费服务(调用方通过@Autowired注入接口即可调用)
//编译器报错,无视。
//因为这个Bean是在程序启动的时候注入的,编译器感知不到,所以报错。
@Autowired
private FeginHiClient feginHiClient;
@GetMapping("/getHi")
public String hiFromFegin() {
return feginHiClient.sayHi();
}
5.启动程序,多次访问http://localhost:8080/getHi
,浏览器交替显示
hi!i am come from 8862hi!
i am come from 8863
至此,使用Feign消费服务已实现,Feign内置ribbon,带负载均衡的效果
@feign的name多个相同时候,解决方案:
@feignname存在多个相同时候,启动会报错, 使用场景在于: 一个微服里面有很多个api,但是又不想全部接口定义在同一个调用接口@feign里面!
第一种: 在配置文件上加上配置: spring.main.allow-bean-definition-overriding=true
第二种: @feign注解是使用contextId属性区分;
@FeignClient(contextId = "fooClient", name = "stores")
public interface FooClient {
//..
}
---------------------------------------------------------
@FeignClient(contextId = "BarClient", name = "stores")
public interface BarClient {
//..
}
扩展:带参数的feign接口写法:
注意 : 有参数一定要有注解并指定参数名称,否则出错
@FeignClient("EUREKA-TEST")
public interface TestService {
@GetMapping("/findOneMap")
Map<String, Object> findOneMap(@RequestParam("id") String id);
}
--------------------------------restful风格 ↓--------------------------------
@FeignClient("tensquare-base")
public interface LabelClient {
@RequestMapping(value="/label/{id}", method = RequestMethod.GET)
public Result findById(@PathVariable("id") String id);
}
----------------------------传递json实体参数使用 @RequestBody ↓----------------------
@RequestMapping(value = "/add",method = RequestMethod.POST)
String add(@RequestBody User user);
Feign的优势(相比RestTemplate)
1.声明式的REST客户端,通过编写简单的接口和插入注解,只需要像调用本地方法一样调用它就可以完成服务请求及相关处理,使REST调用更加简单
若使用RestTemplate,则需要深入了解HTTP级别API的细节。
客户端,通过编写简单的接口和插入注解,只需要像调用本地方法一样调用它就可以完成服务请求及相关处理,使REST调用更加简单
若使用RestTemplate,则需要深入了解HTTP级别API的细节。
2.内置Ribbon,配合Eureka实现负载均衡