官网中叫 Persisting State ,状态持久化。
使用插件时,总会需要保存插件的某些数据,再重启IntelliJ工具时,能接着使用。对于插件数据,IntelliJ分成两类:
- 组件状态:某个组件显示的数据
- 私有数据:各种密码之类的敏感数据
1 处理组件状态
对于 组件 或 服务 的内部状态,IntelliJ提供了两种方式:
- PropertiesComponent:这是一个服务,用来存储临时的、不经常变动的值
- PersistentStateComponent:这是一个普通的Java接口,通过实现这个接口,来处理复杂的数值存储
1.1 PropertiesComponent
这个 Service 的使用非常简单,可以用在 Application 和 Project 级别,存储一些临时的、不经常变动的数据,如下:
// 获取Application级别数据PropertiesComponent appProp = PropertiesComponent.getInstance();// 获取Project级别数据PropertiesComponent proProp = PropertiesComponent.getInstance(Project);// 使用方式appProp.setValue("key", "value");String value = appProp.getValue("key");
使用起来,确实很容易
1.2 PersistentStateComponent
1.2.1 基础使用
插件中,总会用到一些复杂数据,比如:Map,这时,就会用到 PersistentStateComponent 这个接口,用起来也很简单,通常,我们只需:
- 定义一个
Service - 实现
PersistentStateComponent这个接口 - 使用
@com.intellij.openapi.components.State这个注解标明存储位置
就可以了,如下:
单独状态类 :
使用Service字段 :
需要注意的地方:
- 这种方式,只会序列化
public字段,如果要处理private型字段,需要用到注解 - 可以使用
@com.intellij.util.xmlb.annotations.Transient注解来排除不需要序列化的字段 - 状态类必须有一个
默认的构造函数,再第一次加载时,要返回一个默认的状态,不能返回null - 状态类应该实现
equal方法,如果没实现,会通过比较其中的public字段来确认是否相等
这种方式支持的数据类型有:
- number,数字类型:int或Integer等等
- booleans,布尔类型:true或false
- string,字符串型
- collections,集合类型:如List
- maps,映射或叫字典,如:HashMap
-
1.2.2 转换器
有时需要一些类型的转换,比如 时间字符串 转换为 LocalDateTime ,此时可以使用:
com.intellij.util.xmlb.Converter类,需要继承它@com.intellij.util.xmlb.annotations.OptionTag或@com.intellij.util.xmlb.annotations.Attribute类,标明使用地方
如下:
定义 :
class LocalDateTimeConverter extends Converter<LocalDateTime> {public LocalDateTime fromString(String value) {final long epochMilli = Long.parseLong(value);final ZoneId zoneId = ZoneId.systemDefault();return Instant.ofEpochMilli(epochMilli).atZone(zoneId).toLocalDateTime();}public String toString(LocalDateTime value) {final ZoneId zoneId = ZoneId.systemDefault();final long toEpochMilli = value.atZone(zoneId).toInstant().toEpochMilli();return Long.toString(toEpochMilli);}}
使用 :
class State {@OptionTag(converter = LocalDateTimeConverter.class)public LocalDateTime dateTime;}
1.2.3 声明存储位置
通过使用 @com.intellij.openapi.components.State 这个注解来指定数据的存储位置,需要指定以下几个值:
- name,必须的,指定
State的名称,也是存储的xml的根节点 - storages,非必须的,指定了存储文件的位置,可以包含多个存储位置
- reloadable,非必须的,如果设置成false,当存储
xml文件在外部被修改时,而且State也被改变时,要重启整个项目或应用
对于上面的 storages 属性,它包含了 @Storage 属性,通常有以下用法:
@Storage("yourName.xml"),直接指定文件的存储位置@Storage(StoragePathMacros.WORKSPACE_FILE),存储到工作空间
其他的注解:
| 注解 | 说明 |
|---|---|
参考
https://jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html
