天天看点

带你走进 IntelliJ IDEA 的插件世界

作者:冰心de小屋

1. 前言

带你走进 IntelliJ IDEA 的插件世界

工欲善其事,必先利其器!如果开发者比沙场上的战士,那么 IDE 就是战士手中的兵刃,重要程度可想而知,如果 IDE 挑选合适,不仅能让你得心应手,而且还可以事半功倍。

好的 IDE 在开发过程中会为你提供全方外的支持,例如针对于项目方面的:创建、编译、构建和部署等,编码方面的:关键字高亮、语法提示、错误警告、代码自动生成和重构等,其它方面这里不一一列举。但是 IDE 所做的工作不仅如此,为了最大限度的发挥自身价值,提供了插件平台,允许第三方在遵循插件平台集成条款的前提下,使用插件平台对外提供的能力,扩展出更广泛更丰富的功能。这一点上 IntelliJ IDEA 做的非常不错,目前插件数量商业版的已经达到 3000,社区版的 2800 多,其中内容涉及了方方面面,至此插件平台不单单是一个平台,更像一个生态圈,在这个生态圈里面 IntelliJ、第三方和开发者共赢。

说了这么多就想告诉你一点:小小的插件,大大的用途。如果你有兴趣,请跟随我的脚步一起走进 IDEA 的插件世界。

2. 插件安装方式插件

2.1 直接通过 IDEA 内置界面安装

带你走进 IntelliJ IDEA 的插件世界

2.2 安装本地已下载的 IDEA 插件

通过 IDEA 的官网插件地址:https://plugins.jetbrains.com/ 下载 zip 格式的插件文件到本地,之后通过 Preference > Plugins > Install plugin form disk 安装。

成功安装插件后,需要重启 IDEA。

3. 插件文件结构

插件的文件格式是 zip,zip 内必须包含插件配置文件 META-INF/plugin.xml,在 plugin.xml 中必须定义插件的名称、描述、版本以及实现的扩展功能等,下面就是插件的文件结构:

带你走进 IntelliJ IDEA 的插件世界

4. 插件组件

组件是插件集成的基本概念,在 IDEA 中定义了三种不同级别的组件:

4.1 Application level components:应用级别组件

IDEA 在首次启动时会创建该实例,接下来不管启动多少 IDEA 项目,都会共享唯一实例,可以通过 ApplicationManager.getApplication().getComponent(Class<ApplicationComponent> aClass) 获取该实例。

带你走进 IntelliJ IDEA 的插件世界

4.2 Project level components:项目级别组件

带你走进 IntelliJ IDEA 的插件世界

启动一个 IDEA 项目就会创建一个实例,项目之间不共享,模块之间共享,可以通过当前 Project 实例方法:getComponent(Class<ApplicationComponent> aClass) 获取该实例。

4.3 Module level components:模块级别组件

带你走进 IntelliJ IDEA 的插件世界

IDEA 的项目自身可能包含多个模块,那么项目启动时,每个模块会创建一个实例,项目之间、模块之间不共享,可以通过 ModuleManager 根据当前 Project 实例获取:ModuleManager.getInstance(project).getModules()

5. 插件扩展

IDEA 插件平台定义了扩展和扩展点的概念,通过扩展和扩展点,插件与 IDEA 之间的交互成为可能,不仅如此,还可以与其它插件进行交互。

5.1 扩展点

提供插件的同时,如果允许其它插件扩展,必须声明扩展点,针对每个扩展点定义匹配的类或接口。

5.2 平台扩展

扩展 IDEA 平台本身的功能,必须声明一个或多个扩展。

在下面的一幅图中我列举了 IDEA 平台本身的扩展,仅供参考:

带你走进 IntelliJ IDEA 的插件世界

6. 插件动作

ActionIDEA 中菜单栏项目的选择或工具栏按钮的点击,会通过命令模式创建 AnAction 派生类的实例,之后调用派生实例的 actionPerformed 方法。通过 Action 系统你还可以扩展 IDEA 的主菜单、项目菜单、编辑器菜单和工具栏,将插件功能加入其中。

7. 插件配置文件

plugin.xmlplugin.xml 是插件最核心的内容,通过下面的示例说明,你可以了解到 plugin.xml 涉及到的所有层级元素:

<idea-plugin url="http://www.jetbrains.com/idea">
  <!-- 为你的插件设计一个响亮的名字 -->
  <name>VssIntegration</name>


  <!-- 插件的唯一标识,一经创建,永不更改,如为空则依据 name 字段 -->
  <id>VssIntegration</id>


  <!-- 你应该描述下插件具体的功能 -->
  <description>Vss integration plugin</description>


  <!-- 插件随着版本的不断升级的过程中,所做的更改清单 -->
  <change-notes>Initial release of the plugin.</change-notes>


  <!-- 插件版本 -->
  <version>1.0</version>


  <!-- 插件的开发者信息 -->
  <vendor url="错误! 超链接引用无效。 email="[email protected]">[email protected]"/>


  <!-- 依赖插件的唯一标识 -->
  <depends>MyFirstPlugin</depends>
  <!-- 可选择的依赖其它插件标识 -->
  <depends optional="true" config-file="mysecondplugin.xml">MySecondPlugin</depends>


  <!-- 帮助系统支持 -->
  <helpset file="myhelp.jar" path="/Help.hs"/>


  <!-- 插件适用于 IDEA 的版本区间 -->
  <idea-version since-build="3000" until-build="3999"/>


  <!-- 插件多语支持 -->
  <resource-bundle>messages.MyPluginBundle</resource-bundle>


  <!-- 应用级别组件声明 -->
  <application-components>
      <component>
          <interface-class>com.foo.Component1Interface</interface-class>
          <implementation-class>com.foo.impl.Component1Impl</implementation-class>
      </component>
  </application-components>


  <!-- 项目级别组件声明 -->
  <project-components>
      <component>
          <interface-class>com.foo.Component2</interface-class>
          <implementation-class>com.foo.Component2Impl</implementation-class>
          <option name="workspace" value="true"/>
          <loadForDefaultProject/>
      </component>
  </project-components>


  <!-- 模块级别组件声明 module components -->
  <module-components>
      <component>
          <interface-class>com.foo.Component3</interface-class>
          <implementation-class>com.foo.Component3Impl</implementation-class>
      </component>
  </module-components>


  <!-- 动作 -->
  <actions>
      <action id="VssIntegration.GarbageCollection" class="com.foo.impl.CollectGarbage" text="Collect _Garbage"
              description="Run garbage collector">
          <keyboard-shortcut first-keystroke="control alt G" second-keystroke="C" keymap="$default"/>
      </action>
  </actions>


  <!-- 扩展点声明 -->
  <extensionPoints>
      <extensionPoint name="testExtensionPoint" beanClass="com.foo.impl.MyExtensionBean"/>
  </extensionPoints>


  <!-- 扩展声明 -->
  <extensions xmlns="VssIntegration">
      <testExtensionPoint implementation="com.foo.impl.MyExtensionImpl"/>
  </extensions>


</idea-plugin>           

复制代码

8. 插件实践

已经开发了几款插件:

  • TalkingData ORM Tool:根据选择的数据库,匹配数据库中的所有表,自动生成 domain 类、dao 接口和 mapping 文件。
  • TalkingData Jira Integration:方便开发者更好的使用 Jira 进行敏捷开发的工作。
  • My Favorite Code:无论何时何地,收藏精彩的代码片段。

9. 后续

在接下来的章节中会介绍:快速的开发 IDEA 插件,如果你已经仔细的阅读上面的内容,熟知 IDEA 插件的基本概念,相信开发插件绝非难事。

继续阅读