[TOC]
前面的文章中,服务消费者调用服务提供者的接口我们是使用RestTemplate实现的REST API调用的。但这种方式在参数比较多时会变得低效,难以维护。
Feign
Feign是Netflix开发的声明式,模板化的HTTP客户端。它可以让我们更加便捷,优雅的调用HTTP API。Feign有自己的注解,在Spring Cloud中对Feign进行了增强,使其可以支持Spring MVC注解,并整合Ribbon与Eureka。
整合Feign
前面的服务消费都使用RestTemplate来调用服务提供者,这里更改成使用Feign,使用声明式的RestFul API。
添加依赖
1 2 3 4
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
|
配置
配置其实无需修改
1 2 3 4 5 6 7 8 9 10 11
| server: port: 8011 spring: application: name: microservice-consumer-movie eureka: client: service-url: defaultZone: http://user:admin@localhost:8761/eureka/ instance: prefer-ip-address: true
|
创建Feign接口
1 2 3 4 5 6
| @FeignClient(name = "microservice-provider-user") public interface UserFeignClient {
@GetMapping(value = "/{id}") public User findById(@PathVariable("id") Long id); }
|
@FeignClient
注解中的microservice-provider-user
是服务提供者的主机名,用于创建Ribbon负载均衡器,与上篇文章中使用主机名是一样的。也可以使用URL属性指定请求的URL:
@FeignClient(name = "microservice-provider-user",url="http://localhost:8000/")
Controller
1 2 3 4 5 6 7 8 9 10 11 12
| @RestController public class UserController {
@Autowired private UserFeignClient userFeignClient;
@GetMapping("/user/{id}") public User findById(@PathVariable Long id){ return this.userFeignClient.findById(id); } }
|
Controller 中去掉RestTemplate,定义 UserFeignClient 。我在测试中定义的 UserFeignClient 会提示 Could not autowire. No beans of 'UserFeignClient' type found.
但运行并不影响。
添加注解
在启动类上注解 @EnableFeignClients
1 2 3 4 5 6 7 8
| @EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class MicroserviceSimpleConsumerMovieApplication { public static void main(String[] args) { SpringApplication.run(MicroserviceSimpleConsumerMovieApplication.class, args); } }
|
测试
完成上述修改后,就可以像之前一样去调用服务提供者了。
与上篇Ribbon一样,启动一个Eureka,一个或多个服务提供者(Feign自己集成了Ribbon),启动修改完成后的服务消费者。
访问http://localhost:8011/user/1
自定义Feign配置
按上一节整合Feign很简单,但有时候我们想自定义Feign的配置,如更改Feign使用的编码器,解码器,契约,拦截器等。
如服务提供者是需要Http Basic的认证才能调用的,那么服务消费者可以在Feign中自定义配置拦截器,添加 Http Basic 认证。
编写配置类
1 2 3 4 5 6 7 8
| @Configuration public class FooConfiguration {
@Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){ return new BasicAuthRequestInterceptor("user","123456"); } }
|
使用这个配置,只需要在Feign接口类UserFeignClient
的@FeignClient
注解中添加configuration
属性
@FeignClient(name = "microservice-provider-user",configuration="FooConfiguration.class")
另外还需要把服务提供者加上Http Basic认证。
在服务提供都项目中添加security
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
|
在其配置文件中添加用户名与密码:
1 2 3 4 5 6
| security: basic: enabled: true user: name: user password: 123456
|
测试
重新启动服务提供者与服务消费者
这里我们直接去访问服务提供者是需要进行认证的:
访问服务消费者,通过服务消费者去调用服务提供者,不会弹出认证窗口,因为服务消费者在Feign中已经配置了用户名与密码了。
Feign服务间传送文件
转 :Spring Cloud微服务【Finchley.RELEASE版本】(四)使用feign服务间传送文件
Feign构造多参数请求
GET
对于GET请求可以使用Map来构建。接口修改如下 :
1 2 3 4 5
| @FeignClient(name = "microservice-provider-user",configuration = FooConfiguration.class) public interface UserFeignClient { @GetMapping(value = "/get") public User get(@RequestParam Map<String,Object> map); }
|
调用时构建一个Map传递到接口中
POST
post请求则简单得多,可以直接使用 User
实体类
1 2 3 4 5
| @FeignClient(name = "microservice-provider-user",configuration = FooConfiguration.class) public interface UserFeignClient { @PostMapping(value = "/get") public User get(@RequestBody User user); }
|