作者:小傅哥 博客:https://
沉淀、分享、成長,讓自己和他人都能有所收獲!😄
一、前言
不踩些坑,根本不是成熟的碼農(nóng)!
你覺得肯德基全家桶是什么?一家人一起吃的桶嗎,就那么一點點?不是,肯德基全家桶說的是,雞的全家桶!
聽到這個故事就像有時候我因為需要解決某些問題去搜索
、折騰
、驗證
、排除
的技術方案,因為方向不對,所以努力也就白費。只能一次次在眾多的資料、文檔、源碼中一點點找到并組合出適合自己的問題場景的技術處理手段。
但這個過程有時候又是必須經(jīng)歷的,很少有時候能一次就找到正確的答案或者人,哪怕開始就找到了,也會再去排查下其他的資料,看看還有沒有更好的。是不,這就是你吧?
二、拋出問題
我又要沖IDEA插件開發(fā)了!
在研究字節(jié)碼插樁的相關技術后,🤔考慮著除了通常的用在代碼上線后的非入侵式監(jiān)控外,是不是也可以用于研發(fā)在開發(fā)階段對系統(tǒng)接口的提取呢?
帶著這個從腦袋中冒出的想法,想到如果要處理這個事情,最核心的問題就是開發(fā)一款IDEA插件+字節(jié)碼插樁能力,在代碼運行時對運行方法增強,提取相關的必要信息。別說案例還真做出來了,如下:
案例地址:基于IDEA插件開發(fā)和字節(jié)碼插樁技術,實現(xiàn)研發(fā)交付質量自動分析 后續(xù)問題:其實實現(xiàn)到這里還只能算是一個案例,對于 IDEA 插件開發(fā)能力并沒有完全弄透,比如這個 IDEA 插件需要做一些基礎配置,那么在哪里打開呢?還有實時監(jiān)控并產(chǎn)生的接口信息能在 IDEA 界面右側展示出來或者支持導出嗎?如果我再有一些集合 IDEA 插件開發(fā)的能力做的其他的功能引入咋辦呢?這里用到了哪些技術呢?等等,這些問題都需要去一一解決掉,才能完完整整的開發(fā)一個可用的 IDEA 插件,為此,需要做更深入的資料整理和實踐驗證。
三、開發(fā)插件涉及的問題
問題匯總 :開發(fā)一個 IDEA 插件基本要涉及到的問題過程如下:
開發(fā)方式 :在官網(wǎng)的描述中,創(chuàng)建IDEA插件工程的方式有兩種分別是,IntelliJ Platform Plugin 模版創(chuàng)建和 Gradle 構建方式。框架入口 :一個 IDEA 插件開發(fā)完,要考慮把它嵌入到哪,比如是從 IDEA 窗體的 Edit、Tools 等進入配置還是把窗體嵌入到左、右工具條還是IDEA窗體下的對話框。UI :思考的是窗體需要用到什么語言開發(fā),沒錯,用的就是 Swing、Awt 的技術能力。API :在 IDEA 插件開發(fā)中,一般都是圍繞工程進行的,那么基本要從通過 IDEA 插件 JDK 開發(fā)能力中獲取到工程信息、類信息、文件信息等。外部功能 :這一個是用于把插件能力與外部系統(tǒng)結合,比如你是需要把拿到的接口上傳到服務器,還是從遠程下載文件等等。
四、開發(fā)插件的兩種配置
官方文檔:https://plugins./docs/intellij/disposers.html 官方案例:https://github.com/JetBrains/intellij-sdk-docs
1. 基礎配置
IntelliJ IDEA 2019.3.1 x64
JDK 需要配置 IntelliJ Platform Plugin JDK,在 Project Setting 中設置,這樣才可以正常開發(fā) IDEA 插件
id 'org.jetbrains.intellij’ version '0.6.3’
gradle-5.2.1 與 2019 IDEA 版本下的插件開發(fā)匹配
Settings -> Build, Execution,Deloyment -> Build Tools,配置 Gradle。Gradle user home = D:/Program Files (x86)/gradle/gradle-5.2.1/.gradle
User Gradle from =gradle-wrapper.properties
或者 Specified location
具體如下圖:
如果你是使用 IDEA New Project 默認的 IntelliJ Platform Plugin 方式,其實只關注1、2兩步驟就可以了,但如果你需要 Gradle,那么需要注意3、4、5步驟的設置。當然通常也更推薦使用 Gradle 來搭建工程,這樣你在需要一些額外的 Jar 包時候,只需要在 Gradle build.gradle
配置即可,而不是把需要的 Jar 包復制到工程的 lib 下。
2. 遇到問題
在使用 Gradle 構建項目后,你會遇到幾個問題;
提前下載好 Gradle 5.2.1 版本并配置上,否則構建工程自動下載會比較慢 https:///next-steps/?version=5.2.1&format=all 構建工程時候拉取相關內容,會比較慢,如果你有代理會好一些。 【麻煩的問題】基于 Gradle 的 IDEA 插件開發(fā)會在構建過程中,會下載一個匹配版本的 IDEA 軟件用于啟動測試開發(fā)插件,幾百兆那種zip包 ideaIC-2019.3.1.zip
。這個時候基本你會遇到一個崩潰的報錯 Could not resolve all files for configuration ':detachedConfiguration1'.
咋辦呢,如果你不嫌棄麻煩可以手動下載并SHA1加密后把下載的文件放到緩存文件夾中 .gradle\caches\modules-2\files-2.1
具體操作如下:
打開系統(tǒng)盤下當前用戶的.gradle
目錄,進入.gradle\caches\modules-2\files-2.1
目錄,即為緩存文件的目錄。這個目錄是你的報錯構建過程中的報錯地址,Could not get resource D:\Program Files (x86)\gradle\gradle-5.2.1\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2019.3.1
加密文件夾2dae8e50d4b0508cad2e680b53414f657954f390
目錄名稱(你的可能不是這樣的),我去,這個應該是加密 過的,但是是什么加密呢?,經(jīng)過了解知道了這個是SHA1
加密,且是對文件進行SHA1
的加密生成的唯一字符串 ,但是windows上沒有這個命令,在線SHA1
也太麻煩了,還要上傳文件,于是想到了Java的API,還有就是通過git hash
命令行來實現(xiàn)。 把我們的文件ideaIC-2019.3.1.zip
先臨時拷貝到這個目錄。運行sha1sum.exe ideaIC-2019.3.1.zip
命令,生成唯一的唯一字符串(用來校驗文件的完整性),這樣就拿到這個2dae8e50d4b0508cad2e680b53414f657954f390
目錄名 接下來在2019.3.1
目錄下,新建目錄2dae8e50d4b0508cad2e680b53414f657954f390
,將ideaIC-2019.3.1.zip
移動進去即可。 【堆棧溢出】在 Gradle 構建的過程中,消耗內存較大,可能會報錯 Java heap space
所以也可以 在IDEA項目根目錄下,新建文件gradle.properties
,添加如下內容,變更gradle Jvm參數(shù) org.gradle.jvmargs=-Xmx2024m -XX:MaxPermSize=512m
別說還挺好用,竟然構建成功了。
五、寫個測試案例
1. 工程結構
PluginGuide
├── . gradle
└── src
├── main
│ └── java
│ ├── HiClazz . java
│ ├── MyDumbAwareAction . java
│ ├── MySearchableConfigurable . java
│ ├── MyToolWindowFactory . java
│ └── TestUI . java
└── resources
├── icons
└── META- INF
└── plugin. xml
HiClazz 是繼承 AnAction 的實現(xiàn)類,用于附著到 IDEA 的窗體上,點擊后打開對應頁面 MyDumbAwareAction、MyToolWindowFactory,配合使用,用于在 IDEA 最下面的窗體設置,與你看見的控制臺輸出信息位置一樣。 MySearchableConfigurable,可以用于 Settings 中配置窗體。 TestUI 是基于 Swing 開發(fā)的窗體,驗證在 AnAction 實現(xiàn)類中打開。 plugin.xml 是整個 IDEA 咖啡的配置文件,你所有的窗體都會在這個配置文件里有所體現(xiàn)。
2. AnAction
public class HiClazz extends AnAction {
@Override
public void actionPerformed ( AnActionEvent e) {
Project project = e. getData ( PlatformDataKeys . PROJECT) ;
PsiFile psiFile = e. getData ( CommonDataKeys . PSI_FILE) ;
String classPath = psiFile. getVirtualFile ( ) . getPath ( ) ;
String title = "Hello World!" ;
Messages . showMessageDialog ( project, classPath, title, Messages . getInformationIcon ( ) ) ;
}
}
測試在 IDEA 中讀取鼠標停留在類文件中的信息。我們可以把這個 AnAction 配置到各個 IDEA 菜單中。
3. MyToolWindowFactory
public class MyToolWindowFactory implements ToolWindowFactory {
@Override
public void createToolWindowContent ( @NotNull Project project, @NotNull ToolWindow toolWindow) {
toolWindow. setToHideOnEmptyContent ( true ) ;
class MyPanel extends SimpleToolWindowPanel {
public MyPanel ( boolean vertical) {
super ( vertical) ;
DefaultActionGroup group = new DefaultActionGroup ( ) ;
group. add ( new MyDumbAwareAction ( "Login1" ) ) ;
group. add ( new MyDumbAwareAction ( "Login2" ) ) ;
group. add ( new MyDumbAwareAction ( "Login3" ) ) ;
ActionToolbar toolbar = ActionManager . getInstance ( ) . createActionToolbar ( "ToolBar" , group, false ) ;
setToolbar ( toolbar. getComponent ( ) ) ;
}
}
// 添加一個頁
toolWindow. getContentManager ( ) . addContent ( ContentFactory . SERVICE. getInstance ( ) . createContent ( new MyPanel ( false ) , "First" , false ) , 0 ) ;
}
}
在 IDEA 的最下面窗體中,如果想展示自己的窗體,則需要開發(fā)對應的 ToolWindowFactory 實現(xiàn)類,這樣才可以展示你的內容。 這里的思想基本是 Swing 技術的開發(fā)方式,如果你不熟悉 Swing 最這塊內容會比較陌生。
4. plugin.xml
< extensions defaultExtensionNs= "com.intellij" >
< ! -- Add your extensions here -- >
< toolWindow canCloseContents= "true" anchor= "bottom"
id= "SmartIM"
factoryClass= "MyToolWindowFactory" >
< / toolWindow>
< ! -- 在Setting 中添加自定義配置模版 -- >
< projectConfigurable groupId= "Other Settings" displayName= "My Config" id= "thief.id"
instance= "MySearchableConfigurable" / >
< / extensions>
< actions>
< ! -- Add your actions here -- >
< action id= "HiId_FileMenu" class = "HiClazz" text= "HiName" >
< add- to - group group- id= "FileMenu" anchor= "first" / >
< add- to - group group- id= "MainMenu" anchor= "first" / >
< add- to - group group- id= "EditMenu" anchor= "first" / >
< add- to - group group- id= "ViewMenu" anchor= "first" / >
< add- to - group group- id= "CodeMenu" anchor= "first" / >
< add- to - group group- id= "AnalyzeMenu" anchor= "first" / >
< add- to - group group- id= "RefactoringMenu" anchor= "first" / >
< add- to - group group- id= "BuildMenu" anchor= "first" / >
< add- to - group group- id= "RunMenu" anchor= "first" / >
< add- to - group group- id= "ToolsMenu" anchor= "first" / >
< add- to - group group- id= "WindowMenu" anchor= "first" / >
< add- to - group group- id= "HelpMenu" anchor= "first" / >
< / action>
< action id= "HiId_EditorPopupMenu" class = "HiClazz" text= "HiName" >
< add- to - group group- id= "EditorPopupMenu" anchor= "first" / >
< / action>
< action id= "HiId_MainToolBar" class = "HiClazz" text= "HiName" >
< add- to - group group- id= "MainToolBar" anchor= "first" / >
< / action>
< / actions>
在 plugin.xml 的配置中,主要是把各個功能實現(xiàn)窗體配置到對應的菜單下,比如 Tools 下、toolWindow 里等。
5. 測試結果
啟動運行
IDEA 插件開發(fā)運行會基于 Plugin 或者 Gradle 下配置的 ::runIde
運行界面
在 IDEA 的各個菜單中都可以看到新增加的 HiName 插件,在你實際開發(fā)的時候選擇需要的內容進行配置即可。
運行效果
當鼠標點到類的上,在點 HiName 就可以看到對應的工程類信息了。
六、插件開發(fā)能做啥都
在 GitHub 上搜索 IDEA 插件開發(fā),一共有44頁內容,https://github.com/search?p=41&q=idea%E6%8F%92%E4%BB%B6&type=Repositories 涉及到自動化測試、工程腳手架、API生成、生成數(shù)據(jù)庫的DAO類、一些常用工具,當然還有一些比較有意思的,比如:摸魚看書、聽郭德綱相聲、微信聊天、局域網(wǎng)聊天、英語翻譯等等。這里我給大家列舉幾個,開闊開闊思路。
1. 快速生成 CRUD 工程代碼
地址 :https://github.com/mars05/crud-intellij-plugin 描述 :一個增刪改查的idea插件,可以根據(jù)數(shù)據(jù)庫表結構,幫助您快速生成model、dao、service、controller等相關代碼。同時支持MyBatis、JPA、MybatisPlus。
2. 在 IDEA 中摸魚聊天
地址 :https://github.com/Jamling/SmartIM4IntelliJ 描述 :ntelliJ IDEA上的SmartIM(原SmartQQ)插件,可以在IDEA中使用QQ或微信聊天。安裝成功后,會在底部欄出現(xiàn)一個SmartIM的tab(如果沒有底部欄,則在菜單View中把ToolButtons勾選上)
3. 可視化流程編排
地址 :https://github.com/alibaba/compileflow 描述 :compileflow Process
引擎是淘寶工作流TBBPM
引擎之一,是專注于純內存執(zhí)行,無狀態(tài)的流程引擎,通過將流程文件轉換生成java
代碼編譯執(zhí)行,簡潔高效。當前是阿里業(yè)務中臺交易等多個核心系統(tǒng)的流程引擎。在阿里巴巴中臺解決方案中廣泛使用,支撐了導購、交易、履約、資金等多個業(yè)務場景。
七、總結
IDEA 開發(fā)技術涉及到了對 IDEA 插件開發(fā) API 的熟悉以及UI界面的開發(fā),所以如果想開發(fā)一款 IDEA 插件,基本離不開對 Swing 的編寫,不過也不需要太復雜的頁面,所有這部分技能還好。 IDEA 官網(wǎng)文檔僅提供了兩種構建 IDEA 插件工程的方法,但更推薦 Gradle 方式,這樣可以滿足你對后續(xù)其他功能組件的便捷引入,以及做其他內容的擴展。 IDEA 插件開發(fā)可以開發(fā)出很多用于提效研發(fā)編程的技術插件,例如一些監(jiān)控、腳手架、接口API以及調試、流程化低代碼編排等等,所以這部分內容的價值還是蠻大的。
八、系列推薦
基于IDEA插件開發(fā)和字節(jié)碼插樁技術,實現(xiàn)研發(fā)交付質量自動分析 關于低代碼編程的可持續(xù)性交付設計和分析 不重復造輪子都是騙小孩的,教你手擼 SpringBoot 腳手架! 調研字節(jié)碼插樁技術,用于系統(tǒng)監(jiān)控設計和實現(xiàn) 小傅哥,一個有“副業(yè)”的碼農(nóng)!