Idea-Plugin(IntelliJ IDEA 插件)
在 IDEA 内提供:Proto → Java 命令类、MySQL → JPA 实体、Java 类 ↔ JSON、按项目保存的备忘录、提交前本机时间校验。
功能一览
| 功能 | 主要入口 | 说明 |
|---|---|---|
| Proto 转 Java | 右键 .proto、项目树、Tools |
从 proto 生成 @Cmd 命令类 |
| mysql 转 Jpa | 右键文件夹、Tools | 连接 MySQL,多表生成 JPA 实体 |
| Java → JSON | 类名上 Alt+Enter、编辑器右键 | 按字段类型生成带默认值的 JSON |
| Json 转 java | 右键文件夹、Tools | 从 JSON 生成 Java Bean 源文件 |
| 我的自定义备忘录 | Tools、工具窗口 | 按项目保存备忘录 |
| 提交前时间校验 | 提交 / 提交并推送 | 本机时间与网络时间偏差过大时警告 |
1. Proto 转 Java
做什么:从 cmd_rpc.proto(及同目录可选的 pb_service.proto)解析 ServiceNService 与 rpc,在指定目录生成与 comm-framework 风格一致的 @Cmd + AbstractTypedPbCommand Java 类。
怎么用
- 打开符合约定的
.proto(可与pb_service.proto同目录)。 - Proto转Java(编辑器或项目树右键选中
.proto,或 Tools 菜单)。 - 在对话框中勾选 RPC、选择输出目录(如
.../src/main/java/.../cmd/cmds)。 - 确认生成;已存在的同名
.java会跳过。
实现要点
- 入口:
ProtoCmdGeneratorAction;对话框GenerateCmdDialog;生成逻辑ProtoFileParser、JavaCommandGenerator等。 - 输出:通过
PsiFileFactory+WriteCommandAction在目标目录创建.java文件。
约定(Proto)
- Service 命名:
Service1Service、Service2Service、… - Method 枚举:同文件内
ServiceN_Method,去掉Default*后按枚举值从小到大与同一 service 内 rpc 声明顺序 对应。 - PbService:同目录
pb_service.proto的enum PbService中= N的项名;缺失时回退为Service_N。
2. mysql 转 Jpa
做什么:连接 MySQL,列出库表(支持搜索与多选),按表结构生成带 jakarta.persistence 注解的实体类(@Entity、@Table、@Id、@Column 等;复合主键生成 @IdClass)。
怎么用
- 在 Java 源码目录(如
.../src/main/java/你的包路径)上右键文件夹打开对话框,或从 Tools 打开(需在对话框中理解输出目录与包名推断规则)。 - 填写 JDBC(必须含库名,例如
host:3306/your_db或完整jdbc:mysql://.../your_db?...)、用户名、密码。 - 查询表 → 搜索 / 多选表 → 生成 Java 实体。
实现要点
- 入口:
MysqlEntityFromFolderAction;对话框与写文件:mysql包下MysqlEntityDialog、实体生成器等。 - JDBC:插件依赖
mysql-connector-j;URL 须包含库名。 - 包名:优先根据所选目录相对
src/main/java的路径推断(PackageInference)。 - 若目标工程仍为 Spring Boot 2 /
javax.persistence,生成代码中的包名需自行替换或改生成器。
3. Java 类 → JSON(默认值)
做什么:根据当前 Java 类的非 static 实例字段(含继承字段)生成一段 JSON,各类型使用约定默认值(数字 0、布尔 false、字符串 ""、集合 []、Map {}、嵌套类型递归为对象;循环引用处为 null 等)。
怎么用
- 推荐:光标放在类声明上的类名(例如
public class Foo中的Foo),按 Alt+Enter,选择 「是否生成 JSON(默认值)…」。 - 在确认对话框中选 是。
- 在结果弹窗中查看 JSON,可点击 「复制到剪贴板」。
备选:光标在类体内任意位置时,编辑器 右键 → 「生成类JSON(默认值)」,流程相同(先确认再弹窗)。
实现要点
- 意图:
ClassToJsonIntention(注册于plugin.xml的intentionAction,说明见intentionDescriptions/ClassToJsonIntention/)。 - 编辑器菜单:
GenerateClassJsonEditorAction。 - 构建 JSON:
JavaClassToJsonBuilder(PSI 字段与类型 + Gson 格式化);展示:ShowJsonResultDialog。
4. Json 转 java
做什么:根据输入的 JSON 对象(根节点必须是 {})和 Java 类名,在选定目录生成一个 Java Bean 源文件:private 字段 + getter/setter;嵌套对象生成 静态内部类;数组字段推断为 List<…>(元素类型主要依据数组第一个元素)。
怎么用
- 在项目树中右键目标文件夹(一般为
src/main/java/...下某包目录),或使用 Tools → Json转java(须已能确定输出目录;若未选文件夹会提示)。 - 填写 类名(不含
.java)、包名(默认按目录用PackageInference推断)。 - 粘贴 JSON(根为对象)。
- 确定后生成
类名.java;若文件已存在则不覆盖并提示。
实现要点
- 入口:
JsonToJavaAction;对话框:JsonToJavaDialog;解析与代码生成:JsonToJavaGenerator(Gson 解析);字段名规则复用mysql/JavaNames。 - 依赖:Gson(
build.gradle.kts)。
5. 我的自定义备忘录
做什么:右侧工具窗口,对当前 项目 做备忘录的增删改(新建、编辑后保存、删除)。
怎么用
- Tools → 我的自定义备忘录;或在 View → Tool Windows 中找到同名窗口。
- 新建 → 填写标题与正文 → 保存;选中条目可 删除。
- 切换列表项前请先 保存 当前编辑,避免未写入的修改被覆盖。
实现要点
- 工具窗口:
memo/MemoToolWindowFactory等;持久化:MemoProjectService+.idea/protoPluginMemos.xml。 - 工具窗口 ID:
MyCustomMemo(与plugin.xml中一致)。
6. 提交前时间校验(Commit / Commit & Push)
做什么:在 提交 或 提交并推送 前,用 HTTP 响应头里的 Date 作为参考时间,与 本机系统时间 比较;偏差超过 1 分钟 时弹出警告,用户可选择继续或取消本次提交。
怎么用
- 正常走 IDE 的 Commit / Commit and Push 即可;无单独菜单。若本机时间与网络时间相差过大,会看到警告对话框。
实现要点
CommitTimeCheckinHandlerFactory注册CheckinHandler;实际校验在 KotlinTimeSkewCommitCheckHandler(CommitCheck,ExecutionOrder.EARLY)。- 使用 EARLY 是为避免默认 LATE 检查在部分场景下触发 ABORTED → Cancelled,表现为提交界面异常或文件被回退。
- 无法访问外网、拿不到参考时间时:不拦截。Shelf、Create Patch 等本地提交执行器通常不跑该校验。
环境
- JDK 17
- IntelliJ IDEA 2023.3.x Ultimate(与
sinceBuild233 等对齐);gradle.properties可配置ideaLocalPath指向本机安装目录,runIde沙盒使用该 IDEA。若路径不同请修改;未配置时 Gradle 会尝试在线解析2023.3+IU。 - 运行沙箱:若仓库含 Gradle Wrapper,可用
./gradlew runIde;若无 wrapper,可用本机已安装的 Gradle 执行相同任务(见下节)。
国内镜像(已配置)
- Gradle Wrapper:若存在
gradle/wrapper/gradle-wrapper.properties,可使用腾讯云等镜像与合适发行版(如gradle-8.5-all.zip或bin.zip)。 - Maven / 插件仓库:
settings.gradle.kts与build.gradle.kts已优先阿里云等公共仓库。 - IntelliJ Platform SDK:国内常因 CloudFront 导致
UnknownHostException;推荐配置ideaLocalPath或IDEA_LOCAL_PATH,避免下载ideaIU。
ideaLocalPath 在 Program Files 时:拒绝访问
gradle-intellij-plugin 使用本机 IDE 时可能在安装目录写入 Ivy/builtin 元数据;C:\Program Files\… 可能不可写。
处理:将 IDEA 装到用户目录(Toolbox)、或复制到可写盘,再把 ideaLocalPath 指到该根目录(含 lib、plugins)。
Gradle JVM
gradle-intellij-plugin 1.17.x 需 JDK 11+;本项目源码为 17。IDEA 中 Settings → Gradle → Gradle JVM 请选择 17。
runIde 启动日志里的告警/异常(多与本插件代码无关)
| 现象 | 常见原因 | 建议处理 |
|---|---|---|
VFS wasn't safely shut down、Content storage... broken、LocalHistory is lost |
上次沙箱里的 IDEA 未正常退出,虚拟文件系统缓存损坏 | 清沙箱后重跑(见下) |
GradleJvmSupportMatrix + IllegalArgumentException: 25(JavaVersion.parse) |
沙箱内 Gradle 插件 持久化配置损坏,或与 2023.3 内置解析逻辑冲突 | 清沙箱后重跑 |
LoadingState / Should be called at least in the state COMPONENTS_LOADED(Registry) |
平台在极早启动阶段被 VFS 刷新等并发触发,属 IDE 内部时序问题 | 一般可忽略;清沙箱可减轻连带问题 |
Watch roots should be absolute: src/main/java |
当前打开的业务工程里模块源根被记成相对路径,.iml/导入异常 |
在该工程中 Gradle/Maven Reload 或重新导入 |
Project ... not trusted enough |
沙箱安全策略未信任项目 | 在沙箱 IDEA 里对该工程点 Trust Project |
清沙箱(推荐):
./gradlew cleanIdeaSandbox runIde
或先删目录再运行:build/idea-sandbox(Windows 下路径为 build\idea-sandbox)。
每次 runIde 前自动清沙箱(可选,会丢掉沙箱里的设置与最近打开的工程记录):
./gradlew runIde -PfreshSandbox
构建插件 ZIP
./gradlew buildPlugin
若无 gradlew,使用本机 Gradle:
gradle buildPlugin
产物在 build/distributions/(一般为 Idea-Plugin-<version>.zip),在 IDEA Settings → Plugins → Install Plugin from Disk 安装。
若 build / buildPlugin 在 :buildSearchableOptions 阶段报错(如 sun.font.Font2D.getTypographicFamilyName / NoSuchMethodError),多半是 跑该任务的 Java 与 IDEA 自带 JBR 版本不一致。本仓库在 build.gradle.kts 的 tasks { named("buildSearchableOptions") { enabled = false } } 中禁用了该任务;一般插件不需要生成该项。若你必须开启,请删除上述配置并让 Gradle JVM 使用安装目录下的 jbr 再试。
项目结构(主要源码)
| 路径 | 说明 |
|---|---|
ProtoCmdGeneratorAction / GenerateCmdDialog / JavaCommandGenerator |
Proto → Cmd 生成 |
MysqlEntityFromFolderAction / mysql/* |
MySQL 元数据与 JPA 源码生成 |
json/* |
Java→JSON(PSI + Gson)、JSON→Java(对话框 + 生成器)、意图与编辑器 Action |
PackageInference |
由目录路径推断 Java 包名 |
memo/* |
备忘录状态与工具窗口 UI |
vcs/* |
提交前时间校验(CheckinHandlerFactory + Kotlin CommitCheck EARLY) |
META-INF/plugin.xml |
插件描述、Action、Tool Window、Intention、Project Service |