IDEA 插件开发实战
一. 简介
IntelliJ IDEA是一款开发工具,提供很多插件功能,比如阿里规范插件(Alibaba Java Coding Guidelines),但是随着日常业务展开,很多工作重复性编码,浪费很多时间,需要自定义抽象出来一些插件,自动化的方式解决问题,这也是工程师文化的体现。
二.原理
2.1 背景
IntelliJ平台是开源的,基于Apache许可协议,提供很多丰富的工具,提供组件驱动,基于跨平台JVM,可以在创建菜单栏、列表、弹出菜单、对话框等等。可以适用于多种语言,提供相关解析器和PSI模型,解析文件,构建语义模型。
2.2 基本原理
组件模型
负责生命周期管理以及连接组件之间的相互依赖关系。
Application level components,在IDEA启动的时候创建和初始化,可以使用 getComponent(Class) 获取它们。
Project level components,在IDEA中每个Project实例创建的,甚至可以为未打开的项目创建组件,可以使用 getComponent(Class)方法从Project实例中获取它们。
Module level components,它们是为IDEA中加载的每个项目中每个模块创建,使用getComponent(Class)方法可以从Module实例获取模块级别组件。
生命周期:
创建,调用构造函数
初始化,initComponent调用该方法(如果组件实现ApplicationComponent接口)
配置,保存和加载每个组件的状态。(PersistentStateComponent和JDOMExternalizable,实例化配置)。
注册,对于模块组件,将调用接口的moduleAdded方法ModuleComponent将模块添加到项目中,对于项目组件,调用接口的projectOpened方法ProjectComponent加载项目。
保存配置,JDOMExternalizable,PersistentStateComponent的调用。
输出,disposeComponent调用输出。
线程模型
平台相关数据结构由读/写锁覆盖,适用于PSI,VFS 和项目模型。允许从任何线程读取数据。从UI线程读取数据不需要任何特殊的工作。但是,从任何其他线程执行的读取操作都需要使用ApplicationManager.getApplication().runReadAction()或ReadAction.run/compute。
仅允许从UI线程写入数据,并且写入操作始终需要用ApplicationManager.getApplication().runWriteAction()或WriteAction.run()/compute()。
后台流程管理
后台进度由ProgressManager类管理,该类有很多方法可以使用模式(对话框),非模式(在状态栏中可见)或不可见进度来执行给定代码。在所有情况下,代码都是在与ProgressIndicator对象关联的后台线程上执行的。
讯息传递
平台中可用的消息传递基础结构,基于 Observer设计模式扩展实现的,通过该模式能够更好的梳理的一对多关系,实现提供了附加功能,例如在层次结构上进行广播和特殊的嵌套事件处理(此处的嵌套事件是指从另一个事件的回调中(直接或间接)触发新事件的情况)。
2.3 小结
具体相关原理研究,可查看官网(http://www.jetbrains.org/intellij/sdk/docs/welcome.html)。
三.api
3.1 框架结构
.IntelliJIDEA/
└── plugins
└── code_plugin
└── lib
├── lib_foo.jar
├── lib_bar.jar
│ ...
│ ...
└── sample.jar
├── com/foo/...
│ ...
│ ...
└── META-INF
├── plugin.xml
├── pluginIcon.svg
└── pluginIcon_dark.svg
└──src
├──com.code
基本的框架结构,如果要导入依赖放到lib文件夹中,还有另一种建立框架的方式,那个是基于Gradle管理。
META-INF,配置文件件,管理注册的类。
3.2 常用API介绍
VFS
提供一个处理文件的通用API,而不关心文件的具体位置(无论文件位于磁盘上、归档文件中还是HTTP服务器上)。
追踪文件变化,并且在检测到文件内容发生更改时能提供新旧两个版本的文件。
建立文件在VFS和持久化存储之间的关联。
从本地IO文件中获取
对VirtualFile进行读写操作:
和Android一样,Intellij Platform不允许直接在主线程进行实时的文件写入,需要通过一个异步任务进行。
在异步任务结束后,切回UI线程进行UI更新:
PSI
PSI(Program Structure Interface)是Intellij Platform中一个非常重要的概念,在IDE所管理的Project中,每个目录,Package,源代码和资源文件都会被抽象成相应的PSI对象。
常用子类:PsiDirectory、PsiJavaFile和XmlFile。
创建目录和文件:
读写文件:和写入VirtualFile一样,读写操作都需要在WriteCommandAction异步线程中进行。
创建Class文件类:
psiClass类中添加接口:
设置包名:
设置类权限:
四.实例架构
平时开发过程中,代码结构会分层,类似MVC思想,这里面有很多可以抽象出来的公共类,比如JavaBean,DTO,Service等等,我这个实例结合类似场景,实现自动化插件。
架构
五.准备工作
创建插件项目:
还可以用Gradle方式创建项目,我用的idea版本2019.2.4,上述内容中提到框架结构,现在可以在src目录中编码。
六.编码
总共有几个部分组成。
BaseAnAction
AnActionEvent一些基本信息。
CodeComponent
应用管理。
还有一些工具类,比如操作MySQL数据库,操作字符串等等。一些freemarker模板,Action动作。
MMS_DO.java.ft
CreateServiceAction
创建Service接口和实现类。
GitHub项目
项目内容放到GitHub中,地址:https://github.com/77954309/code_plugin.git
有些依赖得自行下载,
七.部署
在code_plugin项目鼠标右击,或者build 点击Prepare Plugin Module '插件名称(codeplugin)' For Deployment 生成插件包(zip/jar)。
在IDEA 文件夹,File->Settings->Plugins->Install Plugin from Disk,安装打出插件,查看目录,重启。
导入插件
效果展示
插件位置
项目,鼠标右击,新建New,有CreateDO、CreateDTO、CreateService三个功能窗口。
创建DO
这个实体是跟MySQL业务表像映射的,窗口填的是数据库表名称。
创建DTO
DTO是跟DO相映射的,符合阿里的编程规范,用于处理Service层业务处理,这个代码中写上包名称,DO得在特定包名下,DTO才能映射。
八.总结
总体的IDEA插件开发介绍完毕,这个可以基于模板快速拓展,有兴趣的朋友可以尝试下,毕竟授人以鱼不如授人以渔,自动化是工程师文化的一个重要体现。
还可以把插件发布到仓库,支持Plugin中搜索安装,参考:
http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/publishing_plugin.html
就是注册账号,提交jar,填写信息,等着审核就可以了。
文中项目地址:https://github.com/77954309/code_plugin
九.作者介绍
李孟,目前就职于知因智慧数据科技有限公司,负责数据中台数据引擎基础架构设计和中间件开发,专注云计算大数据方向。
博客:https://blog.csdn.net/qq_19968255
版权声明: 本文为 InfoQ 作者【李孟】的原创文章。
原文链接:【http://xie.infoq.cn/article/3622db5eb6f77c816512b19dd】。文章转载请联系作者。
评论 (3 条评论)