前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用前端编译简化Feign降级代码

利用前端编译简化Feign降级代码

原创
作者头像
eeaters
修改2022-05-04 01:20:38
3100
修改2022-05-04 01:20:38
举报
文章被收录于专栏:阿杰阿杰

降级FallBack类自动补全的Demo

  • 解决的问题
  • 实现的方案
    • 方案1: 抽离一个专门回退的Client
    • 方案2: 代理类
    • 方案3: 利用APT技术,业务写抽象类,编译器自动完善
  • 项目结构
  • 基本流程
  • 实现的效果
  • 碰到的问题
    • 注意事项
    • 编译期代码如何debug

解决的问题

Feign的服务降级中,一个有20个方法的Client,现在需要对一个方法降级处理, 但是fallback是类级别的定义,所以需要对其他19个也进行代码的编写.

业务方希望我能够解决他们这个问题

这个demo放到了github上: refine-class

实现的方案

方案1: 抽离一个专门回退的Client

需要回退的方法就抽出来和其他的隔离一下,但是业务方提出:

有些方法是发现风险后才决定加回退,那么发现问题就改代码,如果解决不了他们再考虑这种方案

方案2: 代理类

有同事提出方案,通过一个代理类,所有回退都走该代理类, 代理类通过反射进行需要回退的代码调用

因为我不认同这种方案,没有深入思考

方案3: 利用APT技术,业务写抽象类,编译器自动完善

思路来源于lombok,mapstruct框架,编译期进行代码完善

mapstruct利用的freemarker模板引擎,实际demo中感觉太重了,直接参考spring-initializr项目进行实现类编写

项目结构

  1. refine-core 核心jar包,目前只有一个注解
  2. refine-processor 编译的处理器,核心代码都在这里
  3. refine-example 样例模块,测试是否与lombok兼容(兼容的)

基本流程

  1. 开发时,写一个Client的抽象类,将需要降级的代码编写
  2. 在抽象类上加一个注解进行标记: Demo中是@RefineComponent,保留策略为Class而不是经常写的RunTime级别了
  3. 编译器进行代码完善(这个demo存在就为了写这里的代码) -- 参考mapstruct的 MethodRetrievalProcessor 进行扫描,获取要填充的信息 -- 参考spring-initializr项目中对pom.xml的写入方法,写一个实现类

实现的效果

AbstractEcho这个类在编译后生成了一个实现类; 将target中生成的实现类粘贴如下:

代码语言:javascript
复制
package io.eeaters.refine.example;

import io.eeaters.refine.example.entity.Result;
import org.springframework.stereotype.Component;

@Component
public class AbstractEchoImpl extends AbstractEcho {
    public AbstractEchoImpl() {
    }

    public String echo(String var0) {
        return null;
    }

    public Result<String> echo(Result<String> var0, String var1) {
        return null;
    }
}

碰到的问题

注意事项

  1. 这里编写的代码是编译器的,api和运行期的不太一样,反射那套api是绝对不能用的 mapstruct的功能强大所以代码也比较复杂,因此对于 RefineContext#buildMethodInfo 方法是在debug中写的, 不知道能不能经得起线上使用
  2. 目前是将所有的类通过全类名的方法生成的文件,编译后在target中又变成了符合我们阅读的代码,有时间(可能永远没时间)可以在 MetaInfo中加一个importClasses的Set集合; 碰到所有非java.lang全部丢进去,然后write到流中就可以

编译期代码如何debug

代码是在Idea中编写,Idea的debug过程如下:

  1. Run Configuration中增加一个Remote JVM Debug; 端口号设置为8000(参考网上设置的端口号,非必须)
  2. 首次需要在根目录下maven compile/install一下,或者直接根目录下Debug Maven中执行直接进入debug.后面就可以针对example模块执行Debug Maven即可

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决的问题
  • 实现的方案
    • 方案1: 抽离一个专门回退的Client
      • 方案2: 代理类
        • 方案3: 利用APT技术,业务写抽象类,编译器自动完善
        • 项目结构
        • 基本流程
        • 实现的效果
        • 碰到的问题
          • 注意事项
            • 编译期代码如何debug
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档