1、插件内的文件

2、插件类加载器

3、插件组件(component)

4、插件的扩展以及扩展点(Extensions、Extension Points)

5、插件的Action

6、插件的Service

7、插件配置文件结构

8、插件依赖

插件内的文件

有两种方式组织你的插件目录内的文件。

1、插件相关的 jar 文件放在插件根目录下

2、jar 文件放在 lib 文件夹下

如下:实际上,大部分都是插件目录下放个lib文件夹,把插件放到 lib 下。

我们通过 idea 的 build 菜单的 "prepare plugin moudle xxx for deployment" 生成的插件文件内,解压也是一个 lib 文件夹,里面放插件。

除此之外,plugin.xml 文件应该放在 META-INF 文件夹下保存。

插件类加载器

每一个插件都可以有一个独立的类加载器,这样的好处是,允许不同插件可以使用不同版本的库。

默认情况下,插件不会使用 IDE 的类加载器,所以 plugin.xml 中的 depends 的 <depends>com.intellij.modules.platform</depends> 如果不加上去,插件打包之后并不会生效。

你也可以使用 <depends> 元素来指定一个或多个当前插件所依赖的插件,这样一来,我们就可以在当前插件使用其他插件的类加载器,这样我们就可以引用其他插件里面定义的类。

插件组件

插件组件是插件集成的基础概念,有三种组件:

1、应用级组件(Application level components):IDE 启动的时候会创建和初始化。我们可以通过Application 实例来获取这些组件。(通过 ApplicationManager获取Application实例,application.getComponent(Class))

2、项目级组件(Project level components):该类组件为每个 Project 实例创建。我们可以通个 Project 实例来获取这些组件。(通过 Project project = anActionEvent.getData(PlatformDataKeys.PROJECT); 获取 Project 实例,project.getComponent(Class))

3、模块级组件(Module level components):该类组件为每个 project 的 Moudule 创建。我们可以通过 Module 实例来获取这些组件。

我们插件定义的每一个组件(component) 应该在配置文件中配置相关的接口(可选)和实现类,如下:

<application-components>
<component>
<implementation-class>com.eleven24.HelloWorldRegistration</implementation-class>
</component>
</application-components>

配置的实现类将会被用于组件实例化。

两个相同级的组件不能有相同的接口类。

每个组件有一个唯一的名字用来作为外部标识或者内部需要,通过组件的 getComponentName() 返回:

public class HelloWorldRegistration implements ApplicationComponent {
@NotNull
public String getComponentName() {
return "HelloWorldPlugin";
}
}

  

组件命名

推荐使用 <plugin_name>.<component_name> 的方式命名。

应用级组件

一个应用级的组件实现类可以选择是否去实现 ApplicationComponent接口。

一个没有任何依赖的组件应该有一个空参数的构造方法用以实例化。如果组件依赖其他组件,可以在构造方法参数中指定依赖的组件。IntelliJ Platform 会确保以正确的顺序来实例化组件,以保证我们组件可以正确实例化。

应用级组件必须在 plugin.xml的 <application-components> 块中注册。

项目级组件

一个 Project 级的组件可以选择是否去实现 ProjectComponent接口。

一个 project 级的组件如果需要 Project 实例,可以在该组件类的构造方法中指定一个 Project 类型的参数。同时如果依赖其他组件也可以指定其他 Application level 或者 Project level 的组件作为构造方法参数。

project 级组件必须在 plugin.xml 的 <project-components> 块中注册。

模块级组件

一个 Module 级的组件可以选择是否去实现  ModuleComponent接口。

一个 Module 级组件可以在构造方法指定一个 Module 类型的参数。同时如果依赖其他组件,也可以指定 application level、projetc level 或 module level 组件作为参数。

module 级组件必须在 plugin.xml 的 <module-components> 块中注册。

组件状态的持久化

如果组件类实现了  JDOMExternalizable或者  PersistentStateComponent 接口,组件的状态将会自动保存和加载。

当组件类实现了  PersistentStateComponent 接口,组件状态会保存在一个 xml 文件中,你可以通过 @State 和 @Storage 注解来指明当前的状态。

当组件实现了 JDOMExternalizable 接口,组件将会在下面的文件中保存它们的状态:

- project 级的组件的状态会保存在 .ipr 文件中,如果 plugin.xml 的 workspace 选项被设置为 true,将会被保存在 .iws 文件而不是 .ipr 文件中。

- module 级的组件状态将会保存在 .iml 文件中

更多信息可查看:Persisting State of Components

插件默认配置

定义在 <component_name>.xml 文件中,该文件需要放在 默认 package 的 classpath 下。

如果插件有默认配置,readExternal() 将会被调用两次:

1、第一次读取默认配置

2、第二次读取保存的配置

插件组件生命周期

组件按下面的顺序加载:

1、创建 - 构造方法被调用

2、初始化 - initComponent 方法被调用(前提是实现了  ApplicationComponent 接口)

3、配置 - readExternal 方法被调用(前提是实现了  JDOMExternalizable 接口),或者 loadState  被调用 (组件实现了  PersistentStateComponent 接口)

4、对于 module 组件, 如果一个模块被添加到 project, ModuleComponent 接口的 moduleAdded 方法将会被调用。

5、对于 project 组件,如果一个 project 被加载完, ProjectComponent 接口的 projectOpened  方法将会被调用。

组件按下面的顺序卸载:

1、保存配置 - writeExternal  被调用(如果该组件实现了 JDOMExternalizable 接口),getState  被调用(如果组件实现了 PersistentStateComponent 接口)

2、清理 -  组件的 disposeComponent 方法被调用

注意,不能在组件的构造方法中使用 getComponent() 方法去获取其他组件,如果你需要获取其他组件,可以将它们加到构造方法的参数中,或者在 initComponent  方法再进行此种操作。

todo: 添加例子

插件的扩展以及扩展点

Intellij 平台提供了允许一个插件与其他插件或者 IDE 交互的 extensions 以及 extension points 的概念。

extension points

如果你想要你的插件可以被其他插件使用,那么你必须在你的插件内声明一个或多个扩展点(extension points)。每个扩展点定义了允许访问这个点的类或者接口。

extensions

如果你想要你的插件扩展其他插件或者 Intellij 平台,你必须声明一个或多个 extensions

怎样声明 extensions 以及 extension points

你可以在你的 plugin.xml 中的 <extensions> 和 <extensionPoints> 块中定义 extensions 以及 extension points。

定义一个 extension point

intellij 插件结构(文件结构以及概念层面上的结构)的更多相关文章

  1. DB层面上的设计 分库分表 读写分离 集群化 负载均衡

    第1章  引言 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的 互联网应用,每天几十亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的 ...

  2. AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  3. python中基于descriptor的一些概念(上)

    @python中基于descriptor的一些概念(上) python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2 ...

  4. intellij 插件的使用

    目录 intellij 插件的使用 插件的设置 插件推荐 @(目录) intellij 插件的使用 插件的设置 在 IntelliJ IDEA 的安装讲解中我们其实已经知道,IntelliJ IDEA ...

  5. WordPress Checkout插件跨站脚本漏洞和任意文件上传漏洞

    漏洞名称: WordPress Checkout插件跨站脚本漏洞和任意文件上传漏洞 CNNVD编号: CNNVD-201311-015 发布时间: 2013-11-04 更新时间: 2013-11-0 ...

  6. WordPress Lazy SEO插件lazyseo.php脚本任意文件上传漏洞

    漏洞名称: WordPress Lazy SEO插件lazyseo.php脚本任意文件上传漏洞 CNNVD编号: CNNVD-201309-446 发布时间: 2013-09-26 更新时间: 201 ...

  7. IntelliJ插件安装

    1. 插件管理器在线安装 在IntelliJ插件管理页面([FileàSettingsàIDE SettingsàPlugins]),点击[Browse repositories-]按钮,在搜索框内输 ...

  8. C和指针 (pointers on C)——第十章:结构体和联合(上)

    第十章 结构和联合 这个部分先介绍了.运算符,能够供直接訪问,还介绍了->运算符,它取代结构体指针的间接訪问操作(*struct).xxx 这一章新手理解起来不算太难,没有学过操作系统的话理解位 ...

  9. Java程序员必备的Intellij插件

    以下是我用过不错的Intellij插件 1. .ignore 地址:https://plugins.jetbrains.com/plugin/7495--ignore 生成各种ignore文件,一键创 ...

随机推荐

  1. 从武侠中的兵器看待数据访问工具——Hibernate Spring.Data Mybatis

    <泪痕剑>第31集,卓爷大谈自己的兵器,我从中摘录,觉得非常受用. “你错了,我们和武器之间的关系,就好像选择情人一样,不管是否擅长,都要用感情. 我少年时候用刀,青年时候仍用刀,不知道用 ...

  2. 基于zookeeper+mesos+marathon的docker集群管理平台

    参考文档: mesos:http://mesos.apache.org/ mesosphere社区版:https://github.com/mesosphere/open-docs mesospher ...

  3. OA系统与Exchange 日历打通

    目前我碰到好几个案例是希望将客户以后的OA系统与Exchange中的日历系统相结合,比如致远或者泛微的OA系统. 客户的需求如下: 1.有了OA系统 2.客户使用Outlook当邮件客户端 3.客户希 ...

  4. sqlmap+tor解决ip黑名单限制

    1.安装tor浏览器(8.0.8)并配置好 旧版tor是需要Vidalia配合的,新版貌似集成了?还是怎样的,反正不需要了 2.启动tor浏览器 3.启动sqlmap python sqlmap.py ...

  5. 亚马逊AWS业务副总裁:如何在基础设施上降成本

    腾讯科技 林靖东 11月17日编译 亚马逊Amazon Web Services业务的副总裁.著名工程师詹姆斯汉密尔顿(James Hamilton)在AWS re:Invent大会上解释了公司是如何 ...

  6. ASP.NET Web API - 使用 Castle Windsor 依赖注入

    示例代码 项目启动时,创建依赖注入容器 定义一静态容器 IWindsorContainer private static IWindsorContainer _container; 在 Applica ...

  7. phpquery 学习笔记

    phpQuery是一个基于PHP的服务端开源项目,它可以让PHP开发人员轻松处理DOM文档内容,比如获取某新闻网站的头条信息.更有意思的是,它采用了jQuery的思想,你可以像使用jQuery一样处理 ...

  8. php序列化问题

    序列化是将变量转换为可保存或传输的字符串的过程:反序列化就是在适当的时候把这个字符串再转化成原来的变量使用.这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性. 1. serialize和 ...

  9. Unicode 和 UTF-8 有何区别

    作者:于洋链接:https://www.zhihu.com/question/23374078/answer/69732605来源:知乎著作权归作者所有,转载请联系作者获得授权. ========== ...

  10. lintcode-414-两个整数相除

    414-两个整数相除 将两个整数相除,要求不使用乘法.除法和 mod 运算符. 如果溢出,返回 2147483647 . 样例 给定被除数 = 100 ,除数 = 9,返回 11. 标签 二分法 思路 ...