《IntelliJ IDEA 插件开发》第四节:扩展创建工程向导步骤,开发DDD脚手架
持续坚持原创输出,点击蓝字关注我吧
作者:小傅哥
博客:https://bugstack.cn
❝沉淀、分享、成长,让自己和他人都能有所收获!😜
❞
目录
一、前言
二、需求目的
三、案例开发
1. 工程结构
2. UI 工程配置窗体
3. 配置工程步骤创建
4. 开发脚手架服务
5. 调用脚手架服务
6. 配置模板工程
四、测试验证
五、总结
六、系列推荐
一、前言
研发,要避免自嗨!
你做这个东西的价值是什么?有竞品调研吗?能赋能业务吗?那不已经有同类的了,你为什么还自己造轮子?
你是不是也会被问到这样的问题,甚至可能还有些头疼。但做的时候挺嗨,研究技术嘛,还落地了,多刺激。不过要说价值,好像一时半会还体现不出来,能不能赋能业务就不更不一定了。
可谁又能保证以后不能呢,技术的点是一个个攻克尝试的才有机会再深度学习后把这些内容连成一片,就像单说水、单说沙子、单说泥巴,好像并没有啥用,但把它们凑到一块再给把火,就烧成了砖,砖就码成了墙,墙就盖成房。
二、需求目的
我们这一章节把 freemarker 能力与 IDEA Plugin 插件能力结合,开发一个DDD 脚手架 IDEA 插件
,可能你会想为什么要把脚手架开发到插件里呢?还有不是已经有了成型的脚手架可以用吗?
首先我们目前看到的脚手架基本都是网页版的,也就是一次性创建工程使用,不过在我们实际使用的时候,还希望在工程创建过程中把数据库、ES、Redis等生成对应的 ORM 代码,减少开发工作量。并且在使用的工程骨架的过程中,还希望可以随着开发需要再次补充新的功能进去,这个时候网页版的脚手架都不能很好的支持了。此外一些大厂都会自己的技术体系,完全是使用市面的脚手架基本很难满足自身的需求,所以就需要有一个符合自己场景的脚手架了。
那么,我们本章节就把脚手架的开发放到 IDEA 插件开发中,一方面学习脚手架的建设,另外一方面学习如何改变工程向导,创建出自己需要的DDD结构脚手架。
三、案例开发
1. 工程结构
guide-idea-plugin-scaffolding
├── .gradle
└── src
├── main
│ └── java
│ └── cn.bugstack.guide.idea.plugin
│ ├── domain
│ │ ├── model
│ │ │ └── ProjectConfigVO.java
│ │ └── service
│ │ ├── impl
│ │ │ └── ProjectGeneratorImpl.java
│ │ ├── AbstractProjectGenerator.java
│ │ ├── FreemarkerConfiguration.java
│ │ └── IProjectGenerator.java
│ ├── factory
│ │ └── TemplateFactory.java
│ ├── infrastructure
│ │ ├── DataSetting.java
│ │ ├── DataState.java
│ │ ├── ICONS.java
│ │ └── MsgBundle.java
│ ├── module
│ │ ├── DDDModuleBuilder.java
│ │ └── DDDModuleConfigStep.java
│ └── ui
│ ├── ProjectConfigUI.java
│ └── ProjectConfigUI.form
├── resources
│ ├── META-INF
│ │ └── plugin.xml
│ └── template
│ ├── pom.ftl
│ └── yml.ftl
├── build.gradle
└── gradle.properties
源码获取:#公众号:bugstack虫洞栈
回复:idea
即可下载全部 IDEA 插件开发源码
在此 IDEA 插件工程中,主要分为5块区域:
-
domain:领域层,提供创建 DDD 模板工程的服务,其实这部分主要使用的就是 freemarker -
factory:工厂层,提供工程创建模板,这一层的作用就是我们在 IDEA 中创建新工程的时候,可以添加上我们自己的内容,也就是创建出我们定义好的 DDD 工程结构。 -
infrastructure:基础层,提供数据存放、图片加载、信息映射这些功能。 -
module:模块层,提供 DDD 模板工程的创建具体操作和步骤,也就是说我们创建工程的时候是一步步选择的,你可以按需添加自己的步骤页面,允许用户选择和添加自己需要的内容。 比如你需要连库、选择表、添加工程所需要的技术栈等 -
ui:界面层,提供Swing 开发的 UI 界面,用于用户图形化选择和创建。
2. UI 工程配置窗体
public class ProjectConfigUI {
private JPanel mainPanel;
private JTextField groupIdField;
private JTextField artifactIdField;
private JTextField versionField;
private JTextField packageField;
}
-
使用 Swing UI Designer 创建一个配置工厂信息的 UI 窗体,通过这样的方式创建可以直接拖拽。 -
在这个 UI 窗体中我们主要需要; roupId
、artifactId
、version
、package
3. 配置工程步骤创建
3.1 数据存放
cn.bugstack.guide.idea.plugin.infrastructure.DataSetting
@State(name = "DataSetting",storages = @Storage("plugin.xml"))
public class DataSetting implements PersistentStateComponent<DataState> {
private DataState state = new DataState();
public static DataSetting getInstance() {
return ServiceManager.getService(DataSetting.class);
}
@Nullable
@Override
public DataState getState() {
return state;
}
@Override
public void loadState(@NotNull DataState state) {
this.state = state;
}
public ProjectConfigVO getProjectConfig(){
return state.getProjectConfigVO();
}
}
-
在基础层提供数据存放的服务,把创建工程的配置信息存放到服务中,这样比较方便设置和获取。
3.2 扩展步骤
cn.bugstack.guide.idea.plugin.module.DDDModuleConfigStep
public class DDDModuleConfigStep extends ModuleWizardStep {
private ProjectConfigUI projectConfigUI;
public DDDModuleConfigStep(ProjectConfigUI projectConfigUI) {
this.projectConfigUI = projectConfigUI;
}
@Override
public JComponent getComponent() {
return projectConfigUI.getComponent();
}
@Override
public boolean validate() throws ConfigurationException {
// 获取配置信息,写入到 DataSetting
ProjectConfigVO projectConfig = DataSetting.getInstance().getProjectConfig();
projectConfig.set_groupId(projectConfigUI.getGroupIdField().getText());
projectConfig.set_artifactId(projectConfigUI.getArtifactIdField().getText());
projectConfig.set_version(projectConfigUI.getVersionField().getText());
projectConfig.set_package(projectConfigUI.getPackageField().getText());
return super.validate();
}
}
-
继承 ModuleWizardStep
开发一个自己需要的步骤,这个步骤就会出现到我们创建新的工程中。 -
同时在重写的 validate 方法中,把从工程配置 UI 窗体中获取到信息,写入到数据配置文件中。
3.3 配置步骤
cn.bugstack.guide.idea.plugin.module.DDDModuleBuilder
public class DDDModuleBuilder extends ModuleBuilder {
private IProjectGenerator projectGenerator = new ProjectGeneratorImpl();
@Override
public Icon getNodeIcon() {
return ICONS.SPRING_BOOT;
}
/**
* 重写 builderId 挂载自定义模板
*/
@Nullable
@Override
public String getBuilderId() {
return getClass().getName();
}
@Override
public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
// 添加工程配置步骤,可以自己定义需要的步骤,如果有多个可以依次添加
DDDModuleConfigStep moduleConfigStep = new DDDModuleConfigStep(new ProjectConfigUI());
return new ModuleWizardStep[]{moduleConfigStep};
}
}
-
在 createWizardSteps 方法中,把我们已经创建好的 DDDModuleConfigStep
添加工程配置步骤,可以自己定义需要的步骤,如果有多个可以依次添加。 -
同时需要注意,只有重写了 getBuilderId() 方法后,你新增加的向导步骤才能生效。
4. 开发脚手架服务
cn.bugstack.guide.idea.plugin.domain.service.AbstractProjectGenerator
public abstract class AbstractProjectGenerator extends FreemarkerConfiguration implements IProjectGenerator {
@Override
public void doGenerator(Project project, String entryPath, ProjectConfigVO projectConfig) {
// 1.创建工程主POM文件
generateProjectPOM(project, entryPath, projectConfig);
// 2.创建四层架构
generateProjectDDD(project, entryPath, projectConfig);
// 3.创建 Application
generateApplication(project, entryPath, projectConfig);
// 4. 创建 Yml
generateYml(project, entryPath, projectConfig);
// 5. 创建 Common
generateCommon(project, entryPath, projectConfig);
}
}
-
在 domain 领域层添加用于创建脚手架框架的 FreeMarker 服务,它是一款 模板引擎:即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。FreeMarker 在线手册:http://freemarker.foofun.cn -
按照 DDD 工程结构,分层包括:application、domain、infrastructure、interfaces,那么我们把这些创建过程抽象到模板方法中,具体交给子类来创建。
5. 调用脚手架服务
cn.bugstack.guide.idea.plugin.module.DDDModuleBuilder
public class DDDModuleBuilder extends ModuleBuilder {
private IProjectGenerator projectGenerator = new ProjectGeneratorImpl();
@Override
public Icon getNodeIcon() {
return ICONS.SPRING_BOOT;
}
@Override
public void setupRootModel(@NotNull ModifiableRootModel rootModel) throws ConfigurationException {
// 设置 JDK
if (null != this.myJdk) {
rootModel.setSdk(this.myJdk);
} else {
rootModel.inheritSdk();
}
// 生成工程路径
String path = FileUtil.toSystemIndependentName(Objects.requireNonNull(getContentEntryPath()));
new File(path).mkdirs();
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
rootModel.addContentEntry(virtualFile);
Project project = rootModel.getProject();
// 创建工程结构
Runnable r = () -> new WriteCommandAction<VirtualFile>(project) {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
projectGenerator.doGenerator(project, getContentEntryPath(), DataSetting.getInstance().getProjectConfig());
}
}.execute();
}
}
-
在 DDDModuleBuilder#setupRootModel
中,添加创建DDD工程框架
的服务,projectGenerator.doGenerator(project, getContentEntryPath(), DataSetting.getInstance().getProjectConfig());
-
另外这里需要用到 IDEA 提供的线程调用方法, new WriteCommandAction
才能正常创建。
6. 配置模板工程
6.1 模板工厂
cn.bugstack.guide.idea.plugin.factory.TemplateFactory
public class TemplateFactory extends ProjectTemplatesFactory {
@NotNull
@Override
public String[] getGroups() {
return new String[]{"DDD脚手架"};
}
@Override
public Icon getGroupIcon(String group) {
return ICONS.DDD;
}
@NotNull
@Override
public ProjectTemplate[] createTemplates(@Nullable String group, WizardContext context) {
return new ProjectTemplate[]{new BuilderBasedTemplate(new DDDModuleBuilder())};
}
}
-
模板工厂的核心在于把我们用于创建 DDD 的步骤
添加createTemplates
方法中,这样算把整个创建自定义脚手架工程的链路就串联完成了。
6.2 文件配置
plugin.xml
<idea-plugin>
<id>cn.bugstack.guide.idea.plugin.guide-idea-plugin-scaffolding</id>
<name>Scaffolding</name>
<vendor email="184172133@qq.com" url="https://bugstack.cn">小傅哥</vendor>
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<depends>com.intellij.modules.platform</depends>
<extensions defaultExtensionNs="com.intellij">
<projectTemplatesFactory implementation="cn.bugstack.guide.idea.plugin.factory.TemplateFactory"/>
<applicationService serviceImplementation="cn.bugstack.guide.idea.plugin.infrastructure.DataSetting"/>
</extensions>
</idea-plugin>
-
接下来还需要把我们创建的工程模板以及数据服务配置到 plugin.xml
中,这样在插件启动的时候就可以把我们自己插件启动起来了。
四、测试验证
-
点击 Plugin
启动 IDEA 插件,之后创建工程如下:
-
快拿去试试吧,启动插件,点击创建工程,傻瓜式点击,就可以创建出一个 DDD 工程结构了。
五、总结
-
学习使用 IDEA Plugin 开发技术,改变创建工程向导,添加自己需要的工程创建模板,这样就可以创建出一个 DDD 脚手架工程骨架了,接下来你还可以结合自己实际的业务场景添加自己需要的一些技术栈到脚手架中。 -
如果你愿意尝试可以在工程创建中链接到数据库,把数据库中对应的表生成Java代码,这样一些简单的配置、查询、映射,就不用自己动手写了。 -
在开发 DDD 脚手架的源码中还有一些细节过程,包括图标的展示、文案的信息、Freemarker的使用细节,这些你都可以在源码中学习并调试验证。
六、系列推荐
- END -
下方扫码关注 bugstack虫洞栈,与小傅哥一起学习成长、共同进步,做一个码场最贵Coder!
-
回复【设计模式】,获取《重学Java设计模式》,这是一本互联网真实案例的实践书籍,从实际业务中抽离出,交易、营销、秒杀、中间件、源码等众多场景进行学习代码设计。 -
回复【Spring专栏】, 获取《手撸Spring》,这是一本通过带着读者手写简化版 Spring 框架,了解 Spring IOC、AOP、循环依赖等核心原理和设计实现的技术资料。 -
回复【面经手册】,获取《面经手册 • 拿大厂Offer》,这是一本有深度的Java核心内容,从数据结构、算法、并发编程以及JVM系8不断深入讲解,让懂了就是真的懂。
java
工程师、架构师,开发过交易&营销、写过运营&活动、设计过中间件也倒腾过中继器、IO板卡。不只是写Java语言,也搞过C#、PHP,是一个技术活跃的折腾者。 CodeGuide
、 itstack-demo-design
,持续霸榜 Trending,成为全球热门项目。 本文分享自微信公众号 - bugstack虫洞栈(bugstack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
安全研究人员公开了影响多款惠普打印机的两个严重漏洞
据The Hacker News网站报道,安全研究人员周二揭露了影响惠普公司150款多功能打印机(MFP)的两个安全漏洞,攻击者可利用这些漏洞窃取敏感信息,并渗透进企业网络以发起其它攻击。 这两个漏洞统称为Print Shellz,由F-Secure 实验室的研究人员 Timo Hirvonen 和 Alexander Bolshev于今年4月29日首次发现: CVE-2021-39237(CVSS 评分:7.1)- 影响某些 HP LaserJet、HP LaserJet Managed、HP PageWide 和 HP PageWide Managed 打印机的信息泄露漏洞。 CVE-2021-39238(CVSS 评分:9.3)- 影响某些 HP Enterprise LaserJet、HP LaserJet Managed、HP Enterprise PageWide 和 HP PageWide Managed 产品的缓冲区溢出漏洞。 Hirvonen 和 Bolshev 解释说:“漏洞在于设备中的通讯板和解析器,攻击者可以利用它们来获得代码执行权,前者需要物理访问,后者可通过...
- 下一篇
更快更稳更高效!Ubuntu Kylin 20.04 Pro SP1 正式发布
12 月 2 日,优麒麟团队正式宣布 Ubuntu Kylin 20.04 Pro SP1 上线。此版本默认搭载 Linux 5.11 内核,新增显示器显示模式的记忆支持、鼠标拖拽支持等功能,优化网络插件、登录程序和定时关机等系统组件,修复了用户手册程序崩溃、软件商店暂停键刷新不及时、蓝牙传输空文件失败等严重问题, 累计 200+ 桌面环境和应用软件方面的已知问题得到解决,从而全面提升系统稳定性和安全性,为用户提供更加高效便捷的使用体验,欢迎大家下载使用。 全新内核加持,功能支持更强大! UKUI 桌面环境优化,使用更流畅! 自研软件全面升级,体验更高效! 安装方式 1\. 通过官网下载全新安装: https://www.ubuntukylin.com/downloads/ 2\. 已安装 Ubuntu Kylin 20.04 和 20.04 Pro 正式版的用户通过以下方式升级: $ sudo apt update $ sudo apt full-upgrade 系统功能改进与BUG修复日志 桌面环境改动 网络插件 修复开启投屏后,点击无线模块,列表加载失败的问题 修复可...
相关文章
文章评论
共有0条评论来说两句吧...