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编程