Idea 插件开发之DubboInvoke实践

Idea 插件开发之DubboInvoke实践

背景

开发这个插件主要是受一篇阿里技术的文章有所启发,博主当前碰到的问题是在开发联调或者测试中需要调用HSF接口,但是组装一次调用是一个挺费时间的事件,所以想开发一个工具来节省时间,那相应的,我们在使用dubbo的过程中也是存在一样的问题,所以想开发一个dubbo版的idea插件。

参考文章标题:《IDEA 插件神器:5 秒测试一个 HSF 接口》,可以使用sogou的微信搜索。

准备工作

1、下载Intellij IDEA,可以使用社区版,也可以用商业版

2、配置好Java环境

3、配置idea 插件开发环境,主要是配置Intellij Platform SDK,这个一般安装的idea中已经自带了

开发思路

主要是通过dubbo的泛化调用来实现对远程接口的调用,同时通过idea插件帮助拿到接口、方法和入参相关信息,减少人为设置,提高效率。

插件界面使用Java的swing框架, idea插件开发中提供了较为方便的界面开发模式,可以直接拖拽即可完成界面布局。

因为要使用dubbo调用,所以有大量的外部Jar依赖,本来是想使用maven进行依赖管理,但是试了多次发现idea插件开发并不支持,只支持gradle,无奈只能使用gradle,使用gradle中最大的坑是环境问题,就像偶尔碰到maven中的某个依赖一直下载不下来,怎么编译和打包都不通过,实际上通过命令行模式又是可以的,在这个问题上花了2 3个小时,因为不熟悉,一直以为是自己的配置原因,中间还找了大量的开源插件代码,看别人是怎么写build.gradle的,其实我们主要是配置好jar依赖就可以了,其它的基本可以参考 https://github.com/JetBrains/gradle-intellij-plugin/ 中的文档就可以解决。

关于gradle最终怎么打成一个zip包,提供给别人使用, 使用如下配置:

buildPlugin {
    doLast {
        copy {
            from 'build/distributions'
            include "${intellij.pluginName}-${project.version}.zip"
            into "snapshot"
        }
    }
}

整体流程

识别当前光标的位置,获取接口和方法,再拿到方法的所有参数类型(这里主要是因为dubbo调用需要指定参数类型),同时保存当前接口的所有方法和方法对应的入参类型,在用户切换方法时,可以方便带出对应的入参类型,dubbo泛化配置中的zk和group直接使用默认值,允许用户进行修改。

关键代码

    private Pair<PsiClass,PsiMethod> getPsiMethodFromContext(AnActionEvent e) {
        PsiElement elementAt = getPsiElement(e);
        if (elementAt == null) {
            return null;
        }
        // 获取当前类和当前选中的方法, 方法可能为空
        return Pair.of(PsiTreeUtil.getParentOfType(elementAt, PsiClass.class),PsiTreeUtil.getParentOfType(elementAt, PsiMethod.class));
    }

    private PsiElement getPsiElement(AnActionEvent e) {
        PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
        Editor editor = e.getData(PlatformDataKeys.EDITOR);
        if (psiFile == null || editor == null) {
            e.getPresentation().setEnabled(false);
            return null;
        }
        //用来获取当前光标处的PsiElement
        int offset = editor.getCaretModel().getOffset();
        return psiFile.findElementAt(offset);
    }

监听「调用」按钮事件,创建GenericService, 获取页面填入的所有参数,解析入参json,这里使用了soul开源项目中的部分代码,通过GsonUtil解析入参,最后执行调用。

碰到的问题和坑

1、gradle环境问题
不管执行什么命令都一直提示失败,最后使用命令行模式和重新导入项目,再进行clean解决

2、使用apache dubbo进行泛化调用,报找不到扩展的问题
最后换成了alibaba dubbo解决,本来是准备参考hop的代码,但是发现hop还没有升级dubbo版本,所以暂时换回alibaba dubbo,这两个版本的协议也是兼容的。
这里说明下,因为我们之前是用的dubbox,现在正在升级到apache dubbo,这两个协议是不兼容的,所以这种情况下就需要进行特殊处理。

3、gradle 打包成zip或者jar插件提供给使用方
默认打出来的jar是没有包含所有依赖的,所以这里要特殊处理

buildPlugin {
    doLast {
        copy {
            from 'build/distributions'
            include "${intellij.pluginName}-${project.version}.zip"
            into "snapshot"
        }
    }
}

4、依赖包仓库配置

repositories {
	  // 使用本地的.m2/ 仓库
    mavenLocal()
    // 使用中央仓库
    mavenCentral()
}

整个写下来,碰到的最多的问题还是使用gradle中的问题,其它的都是很普通的技术。

后续的一些优化点 1、调用的历史记录可以保存下来,方便后续重复使用 2、当用户手动更换接口后,无法自动找到相应的所有方法和方法入参类型,这个需要用户手动补齐,所以这个插件的使用场景还是在开发中,方便进行dubbo调用而设计的,对于其它场景的dubbo调用,还是要用户自己解决。 3、当前接口下的所有方法可以通过下拉的方式供用户进行选择,避免方法写错的尴尬。

参考资料

https://github.com/JetBrains/gradle-intellij-plugin/

https://github.com/MCMicS/jenkins-control-plugin/blob/master/build.gradle

https://mp.weixin.qq.com/s?src=11×tamp=1593075337&ver=2421&signature=IIGYVtOg2bk4K2ZBewClv8W2nNnPl2Jm04l-TpWNxBFsVljHnzeBMzg9kXCKUEw9OAm7CSB3xlcubXatQyE5K4V7s5x9y1WsxibVn7qmaEQtUXCQFOW4ooODHPKLmA&new=1

https://mp.weixin.qq.com/s?src=11×tamp=1593078787&ver=2422&signature=jlLRIZLSWxnPABIiyhDzKM1yPytzvUB9K52nD7OTALQY2ZRK3I8Rc7F-WHvhyoimGpnFHztIPZI1xMyLmZU4XrOVCe2nWMM3Ft31fN4Vw6y7AJ8PYBcmOBXzgMw9Hj&new=1

https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system.html

知识点

  • gradle

    • 创建gradle工程
    • gradle的一些基本概念
    • gradle的dependencies 配置
    • gradle的仓库配置
  • dubbo泛化调用

  • Java swing编程

原文地址:https://www.cnblogs.com/yissheng/p/13413183.html