目录


  • 前言
  • Feign
  • 整合Feign
  • 添加依赖
  • 配置
  • 创建Feign接口
  • Controller
  • 添加注解
  • 测试
  • 自定义Feign配置
  • 编写配置类
  • 测试
  • Feign服务间传送文件
  • Feign构造多参数请求
  • GET
  • POST



前言

前面的文章中,服务消费者调用服务提供者的接口我们是使用RestTemplate实现的REST API调用的。但这种方式在参数比较多时会变得低效,难以维护。

Feign

Feign是Netflix开发的声明式,模板化的HTTP客户端。它可以让我们更加便捷,优雅的调用HTTP API。Feign有自己的注解,在Spring Cloud中对Feign进行了增强,使其可以支持Spring MVC注解,并整合Ribbon与Eureka。

整合Feign

前面的服务消费都使用RestTemplate来调用服务提供者,这里更改成使用Feign,使用声明式的RestFul API。

添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

配置

配置其实无需修改

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接口

@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

@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

@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

微服务接口返回map 微服务restful调用_微服务接口返回map

自定义Feign配置

按上一节整合Feign很简单,但有时候我们想自定义Feign的配置,如更改Feign使用的编码器,解码器,契约,拦截器等。
如服务提供者是需要Http Basic的认证才能调用的,那么服务消费者可以在Feign中自定义配置拦截器,添加 Http Basic 认证。

编写配置类

@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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

在其配置文件中添加用户名与密码:

security:
  basic:
    enabled: true
  user:
    name: user
    password: 123456

测试

重新启动服务提供者与服务消费者

这里我们直接去访问服务提供者是需要进行认证的:

微服务接口返回map 微服务restful调用_ide_02


访问服务消费者,通过服务消费者去调用服务提供者,不会弹出认证窗口,因为服务消费者在Feign中已经配置了用户名与密码了。

微服务接口返回map 微服务restful调用_ide_03

Feign服务间传送文件

Feign构造多参数请求

GET

对于GET请求可以使用Map来构建。接口修改如下 :

@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 实体类

@FeignClient(name = "microservice-provider-user",configuration = FooConfiguration.class)
public interface UserFeignClient {
    @PostMapping(value = "/get")
    public User get(@RequestBody User user);
}