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