SpringCloud Alibaba 微服务(三):OpenFeign

目录

前言

一、什么是OpenFeign?

Feign 的实现

Feign 和 OpenFeign 的区别

二、OpenFeign的优点

三、基本用法

新建子工程

配置文件

服务注册

​编辑

新建Controller

引入依赖

创建接口

启动类开启Feign注解

访问测试

四、@FeignClient 标签的常用属性

1、name

2、url

3、configuration

4、fallback

5、fallbackFactory

6、path

7、decode404

8、primary

9、contextId

五、添加请求头信息

1、在方法参数上添加请求头信息

2、使用 Feign 配置类定义请求拦截器

定义请求拦截器

应用配置类

3、动态添加请求头信息

总结


前言

在微服务架构中,服务之间的通信是一个非常重要的环节。为了简化和高效地进行服务间通信,Spring Cloud 提供了 OpenFeign 这个强大的工具。本文将介绍 OpenFeign 的概念、优点、基本用法以及在实际项目中的应用。也希望通过本文,能够帮助你们在 Spring Cloud 项目中轻松地集成和使用 OpenFeign。


一、什么是OpenFeign?

OpenFeign 是一个声明式的 HTTP 客户端,用于简化微服务间的 HTTP 调用。它集成了 Ribbon 以实现负载均衡,并且与 Eureka、Consul 等服务发现组件无缝对接。通过使用 OpenFeign,开发者只需要定义接口并使用注解来配置 HTTP 请求,而无需编写大量的模板代码。

Feign 的实现

Feign 在 Ribbon + RestTemplate 基础上做了进一步封装, 它来帮助我们定义和实现依赖服务接口的定义。在 Feign 的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是在 Dao 接口上面标注 Mapper 注解,现在是一个 Service 接口上面标注 Feign 注解),即可完成对服务提供方的接口绑定,简化了使用 Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。

Feign 和 OpenFeign 的区别

依赖

作用

Feign

org.springframework.cloud   spring-cloud-starter-feign

Feign 是 Spring Cloud 组件中的一个轻量级 RESTful 的 HTTP 服务客户端。Feign 内置了 Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign 的使用方式是:使用 Feign 的注解定义接口,调用这个接口就可以调用服务注册中心的服务。

OpenFeign

org.springframework.cloud spring-cloud-starter-openfeign

OpenFeign 是 Spring Cloud 在Feign 的基础上支持了 SpringMVC的注解如 @RequesMapping 等等。OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

二、OpenFeign的优点

声明式调用:通过注解定义 HTTP 请求,代码更简洁。

集成 Ribbon:支持客户端负载均衡。

支持服务发现:与 Eureka、Consul 等服务发现组件无缝集成。

支持熔断:与 Hystrix、Sentinel 等熔断器集成,提升系统稳定性。

可扩展:支持自定义拦截器、编码器和解码器,便于扩展和定制化。

三、基本用法

新建子工程

配置文件

server:
  port: 9091

spring:
  application:
    name: demo-order
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.85:8848
        namespace: demo
      config:
        server-addr: 192.168.1.85:8848
        prefix: ${spring.application.name}
        file-extension: yml
        namespace: demo
<dependencies>
    <!-- Nacos 服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

服务注册

新建Controller

引入依赖

user模块引入OpenFeign依赖

创建接口

启动类开启Feign注解

在用户模块的启动类,加上 @EnableFeignClients 注解。

访问测试

如图所示,证明已经访问成功了。

四、@FeignClient 标签的常用属性

@FeignClient 注解是 Spring Cloud OpenFeign 中用于声明一个 Feign 客户端的核心注解。它可以用来指定服务的名称、配置类、负载均衡策略等。下面是 @FeignClient 注解的一些常用属性及其用途:

1、name

name 属性用于指定 Feign 客户端调用的服务名称。这是一个必填属性,通常是注册在服务发现(如 Nacos)中的服务名。

@FeignClient(name = "demo-user")
public interface UserClient {
    // ...
}

2、url

url 属性用于指定服务的 URL,通常用于调试或服务未注册到服务发现时。url 属性会覆盖 name 属性。

@FeignClient(name = "demo-user", url = "http://localhost:8080")
public interface UserClient {
    // ...
}

3、configuration

configuration 属性用于指定自定义配置类,配置类可以用来定制 Feign 客户端的行为,如请求拦截器、编码器和解码器等。

@FeignClient(name = "demo-user", configuration = FeignConfig.class)
public interface UserClient {
    // ...
}

配置类示例

@Configuration
public class FeignConfig {
    @Bean
    public RequestInterceptor requestInterceptor() {
        return template -> template.header("Custom-Header", "CustomHeaderValue");
    }
}

4、fallback

fallback 属性用于指定服务降级的实现类。当 Feign 客户端调用失败时,会调用 fallback 指定的类中的方法。

@FeignClient(name = "demo-user", fallback = UserClientFallback.class)
public interface UserClient {
    // ...
}

@Component
public class UserClientFallback implements UserClient {
    @Override
    public User getUserById(Long id) {
        return new User(); // 返回一个默认的用户对象
    }
}

5、fallbackFactory

fallbackFactory 属性用于指定服务降级的工厂类,该工厂类可以提供更多的上下文信息,例如异常信息。

@FeignClient(name = "demo-user", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
    // ...
}

@Component
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
    @Override
    public UserClient create(Throwable cause) {
        return new UserClient() {
            @Override
            public User getUserById(Long id) {
                // 返回一个默认的用户对象,并打印异常信息
                System.out.println("Fallback cause: " + cause);
                return new User();
            }
        };
    }
}

6、path

path 属性用于指定服务的统一前缀路径,在定义 Feign 接口的方法时可以省略该路径。

@FeignClient(name = "demo-user", path = "/api/users")
public interface UserClient {
    @GetMapping("/{id}")
    User getUserById(@PathVariable("id") Long id);
}

7、decode404

decode404属性用于指定是否将 HTTP 404 响应解码为 Feign 客户端的 fallback,默认值为 false。

@FeignClient(name = "demo-user", decode404 = true)
public interface UserClient {
    // ...
}

8、primary

primary属性用于指定该 Feign 客户端是否为主要的 @Primary Bean,这对某些场景下的自动装配很有用,默认值为 true。

@FeignClient(name = "demo-user", primary = false)
public interface UserClient {
    // ...
}

9、contextId

contextId 属性用于在多 Feign 客户端实例中区分不同的上下文 ID。特别适用于多个 Feign 客户端指向同一服务时的配置。

@FeignClient(name = "demo-user", contextId = "userClient1")
public interface UserClient1 {
    // ...
}

@FeignClient(name = "demo-user", contextId = "userClient2")
public interface UserClient2 {
    // ...
}

@FeignClient 注解通过丰富的属性配置,提供了强大的功能来满足不同场景下的微服务调用需求。通过合理使用这些属性,可以定制化 Feign 客户端的行为,提升微服务间的通信效率和容错能力。

五、添加请求头信息

1、在方法参数上添加请求头信息

示例:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;

@FeignClient(name = "demo-user")
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") Long id, @RequestHeader("Authorization") String token);
}

在调用接口时,传递请求头参数:

@RestController
public class UserController {
    
    @Autowired
    private UserClient userClient;

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable("id") Long id) {
        String token = "xxxxxxxxxxxxxxxxxxxx";
        return userClient.getUserById(id, token);
    }
}

2、使用 Feign 配置类定义请求拦截器

如果需要在所有请求中添加相同的请求头,可以通过定义一个 Feign 请求拦截器来实现。

定义请求拦截器

创建一个 Feign 配置类,并定义请求拦截器:

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor requestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                template.header("Authorization", "xxxxxxxxxxxxxxxxx");
            }
        };
    }
}

应用配置类

在 Feign 客户端接口上指定配置类:

@FeignClient(name = "demo-user", configuration = FeignConfig.class)
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") Long id);
}

这样,每次调用 UserClient 的方法时,请求头中都会自动包含 Authorization:xxxxxxxxxxxxx

3、动态添加请求头信息

如果需要根据某些条件动态添加请求头信息,可以在拦截器中编写逻辑:

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor requestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (attributes != null) {
                    HttpServletRequest request = attributes.getRequest();
                    String token = request.getHeader("Authorization");
                    if (token != null) {
                        template.header("Authorization", token);
                    }
                }
            }
        };
    }
}

这种方式可以将来自原始 HTTP 请求的请求头信息传递给 Feign 客户端的请求。


总结

本文介绍了 OpenFeign 的基本概念、优点以及在 Spring Boot 项目中的基本用法。OpenFeign 作为声明式的 HTTP 客户端,大大简化了微服务间的通信,使代码更加简洁和易于维护。在实际项目中,OpenFeign 还提供了许多高级特性,如超时设置、自定义拦截器和熔断器集成等,可以根据具体需求进行灵活配置。

  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仅此而已丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值