聊聊我认为的OpenFeign

Posted 又见阿郎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊我认为的OpenFeign相关的知识,希望对你有一定的参考价值。

此篇文章不从源码角度解析,网上一搜一大把。我个人的习惯是自己评估与思考下大概的设计思路是什么,然后看源码与博客佐证。否则一来就是使用然后看源码,一坨一坨的代码,真的看的头疼。以上仅是个人的学习方法。

聊聊OpenFeign,其实这个框架,之前用过,但没留意太多;说白了这个框架的出现就是为了让我们做RPC调用时偷个懒,是的,程序猿到了一定的境界都是想着偷懒。

OpenFeign是集成到了Spring Cloud基于Feign框架实现调用的,因此主要就是Spring容器如何管理Feign中关键对象的问题了。其实说白了最关键的就是这个。任何的原生框架只要集成到Spring框架中,就一定要解决这个问题。

从使用来看,OpenFeign只是定义了两个注解,而且注解还是标注在接口上,没任何的实现类,这妥妥的偷懒神器!因此要集成到Spring中,就需要考虑这些接口的问题了。

比如我有一个DemoController,接口是DemoClient。

那么如何在DemoController中调用DemoClient接口的方法是直接可以通过Spring容器的@Autowired注解解析而后调用接口方法呢?感觉有点熟悉,是的Mybatis集成到Spring,也是一样的。一个Mapper接口,然后就是一堆的方法,加上注解,在Controller中一调用@Autowired注解,得,直接返回成型的数据了。其实这两原理是一样的。

前面大概梳理了下思路,当然只是一部分。但也是最最关键的一个入口。

OpenFeign通过@Import注解引入实现了ImportBeanDefinitionRegister接口的FeignClientsRegistrar类;该类会初始化以及解析相应的配置。比如是否启用,哪些接口标识了要进行RPC调用的等。

OpenFeign定义了FactoryBean工厂实现接口类在Spring容器中的注入;

以上最关键的集成动作其实就是做完了的。如此,Feign其实就算集成进来了。

接下来就是实际的调用。

DemoClient是一个接口,我们实际调用的时候是接口中的某个方法。因此,就需要在调用方法是拦截,走代理的方式在调用处理器中加入逻辑。这个逻辑就是方法API与方法处理器的映射。

比如我调用DemoClient的hello方法,其实就是在调用远程服务的/xxx/hello  API。因此需要拦截调用。把Spring MVC上的注解逻辑解析生成调用的API,最后发起客户端调用。

而客户端调用的逻辑是什么?不就是HttpClient的Get与Post调用了么!

泳道图如下

 

还在用 OpenFeign?来试试 SpringBoot3 中的这个新玩意!

好久没发技术文章了,最近回到工作地,晚上有空又可以码码技术了,今天我们就来聊一个 Spring Boot3 中的新鲜玩意,声明式 HTTP 调用。

1. 由来

Spring Boot3 去年底就已经正式发布,我也尝了一把鲜,最近有空会和小伙伴们慢慢聊聊 Spring Boot3 都给我们带来了哪些新东西。

今天我们就先来看看声明式 HTTP 接口。

用过 Spring Cloud 的小伙伴都知道,在 Spring Cloud 家族中,负责进程间通信的,我们可以使用 RestTemplate 或者 OpenFeign(当然也有其他方式如基于消息中间件的消息驱动的微服务或者基于 gRPC 的调用等)。

RestTemplate 我们可以将之当作一个普普通通的 HTTP 调用工具来对待,区别于其他的 HTTP 客户端,RestTemplate 用来调用 RESTful 风格的接口特别方便。

不过,比 RestTemplate 更加方便的是 OpenFeign,通过接口声明就可以实现远程调用,这些的具体用法松哥在之前的视频中讲过,这里就不再赘述了。

以前我们想要用声明式 HTTP 调用,需要通过 OpenFeign 来实现,这个需要第三方的依赖,从 Spring6 开始(Spring Boot3),Spring 自己提供了类似的功能通过 @HttpExchange 注解也能方便的实现 声明式 HTTP 调用。以后跨服务调用又多了一个选择。

2. 使用

接下来松哥通过一个案例来和小伙伴们演示一下 @HttpExchange 注解的具体玩法。

首先我们先创建一个普通的名为 server 的 Spring Boot 项目,这个普通的 Spring Boot 项目中只需要提供一个简单的测试接口即可,如下:

@RestController
public class HelloController 

    @GetMapping("/server/hello")
    public String hello(String name) 
        return "hello " + name;
    


这个对大家来说应该是没什么难度的,我就不多说了。

现在假设我有另外一个服务名为 client,我想在 client 中调用 server 中提供的这个接口。

首先我们来创建 client 这个项目,大家注意,创建的时候我们不仅需要添加 Web 依赖,还需要 Reactive Web,因为这个 @HttpExchange 底层基于 WebClient,而 WebClient 则是 Reactive Web 提供的:

创建完成后,接下来我们就可以声明 Http 接口了:

@HttpExchange("/server")
public interface ToDoService 
    @GetExchange("/hello")
    String hello(@RequestParam String name);

这些用法跟我们在 SpringMVC 中常用的 @RequestMapping 和 @GetMapping 等特别类似:

  • @HttpExchange 类似于 @RequestMapping,可以将之放在类上,起到一个请求窄化的作用,也可以放在方法上,放在方法上我们可以通过 method 属性来指定具体的请求方法,这个也跟 @RequestMapping 类似: @HttpExchange(value = "/server",method = "GET")
  • @GetExchange 类似于 @GetMapping,这个就不再赘述了,其他类似的注解还有 @DeleteExchange@PatchExchange@PostExchange@PutExchange 等。
  • 另外需要注意的是请求方法的参数需要加上 @RequestParam 注解,这一点和 OpenFeign 比较类似。

接口声明好之后还没完,我们还需要配置一下才能使用。如下:

@Configuration
public class WebConfig 
    @Bean
    WebClient webClient() 
        return WebClient.builder()
                .baseUrl("http://localhost:8080")
                .build();
    
    @Bean
    ToDoService toDoService() 
        HttpServiceProxyFactory httpServiceProxyFactory =
                HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient()))
                        .build();
        return httpServiceProxyFactory.createClient(ToDoService.class);
    

这个配置主要是两方面:

  1. @HttpExchange 是基于 WebClient 的,所以我们首先需要配置 WebClient,配置 WebClient 的时候,也顺便配置了请求的具体地址(因为在 @HttpExchange 注解中并未指定请求的具体域名端口啥的);同时,对于 HTTP 请求头等如果需要定制,也是通过配置 WebClient 来实现的。
  2. 由于我们前面提供的 ToDoService 是一个接口,所以我们还需要提供一个该接口的实现类,当然这个配置完全是套路化模版化的,这块就没啥好说了。

全部配置完成后,接下来我们就可以在任何需要的地方,直接注入 ToDoService 的实例去使用了,举一个简单的例子小伙伴们参考下:

@SpringBootTest
class ClientApplicationTests 

    @Autowired
    ToDoService toDoService;

    @Test
    void contextLoads() 
        String hello = toDoService.hello("javaboy");
        System.out.println("hello = " + hello);
    


好啦,一个简单的例子,小伙伴们不妨体验下。

以后,不用 OpenFeign 也能实现声明式服务调用啦~

以上是关于聊聊我认为的OpenFeign的主要内容,如果未能解决你的问题,请参考以下文章

未找到依赖项:openfeign

openfeign自定义异常不走降级

netflix.feign 和 openfeign 的区别

启用 Spring-Cloud-OpenFeign 配置可刷新,项目无法启动,我 TM 人傻了(上)

聊聊一对一沟通的方法

Nacos:Nacos与OpenFeign的对接使用