Develop a DDD scaffold based on IDEA Plugin

Keywords: Java Back-end

Author: Xiao Fu Ge

Precipitate, share and grow, so that you and others can gain something! 😄

  • Recently, I am interested in expanding various functions in combination with the development capability of IDEA Plugin. Based on this, different cases are used to explore the IDEA Plugin plug-in development technology. I hope this systematic learning and verification summary can help more partners who need this technology.
  • Source address:

1, Foreword

R & D, to avoid self hi!

What is the value of doing this? Is there any competitive product research? Can you enable business? There are already similar ones. Why do you make your own wheels?

Will you also be asked such questions, and may even have a headache. But when doing it, I was very hi. I studied technology and landed. It's so exciting. However, when it comes to value, it seems that it can't be reflected for a while, and it's not certain whether it can empower the business.

But who can guarantee that they will not be able to do so in the future? Only by trying to overcome the technical points one by one can we have the opportunity to connect these contents after in-depth learning, just like talking about water, sand and mud alone. It seems to be of no use, but when they are gathered together and put into a fire, they will be burned into bricks, bricks will be built into walls, and walls will be built into houses.

2, Demand purpose

In this chapter, we combine freemaker capability with IDEA Plugin capability to develop an IDEA Plugin for DDD scaffold. You may wonder why you want to develop scaffold into the plugin? Also, isn't there a formed scaffold that can be used?

First of all, the scaffolds we see at present are basically web versions, that is, they are used to create projects at one time. However, when we actually use them, we also hope to generate corresponding ORM codes from databases, ES, Redis, etc. in the process of project creation, so as to reduce the development workload. And in the process of using the engineering skeleton, I hope to add new functions again as the development needs. At this time, the scaffold of the web version can not be well supported. In addition, some large factories have their own technical system, which is completely using the scaffold on the market, which is basically difficult to meet their own needs, so they need a scaffold that meets their own scenes.

Then, in this chapter, we put the development of scaffold into the development of IDEA plug-in. On the one hand, we learn the construction of scaffold, on the other hand, we learn how to change the engineering wizard and create the DDD structure scaffold we need.

3, Case development

1. Engineering structure

├── .gradle
└── src
    ├── main
    │   └── java
    │   	└── 
    │       	├── domain
    │       	│	 ├── model   
    │       	│	 │	└──       
    │       	│	 └── service   
    │       	│	 	 ├── impl     
    │       	│	 	 │	└──  
    │       	│	 	 ├──     
    │       	│	 	 ├──      
    │       	│	 	 └──      
    │       	├── factory
    │       	│	  └──  
    │       	├── infrastructure
    │       	│	 ├──       
    │       	│	 ├──  
    │       	│	 ├──      
    │       	│	 └──     
    │       	├── module  
    │       	│	 ├──    
    │       	│	 └──         
    │       	└── ui
    │       	 	 ├──  
    │       	 	 └── ProjectConfigUI.form
    ├── resources
    │   ├── META-INF
    │   │   └── plugin.xml 
    │   └── template
    │       ├── pom.ftl
    │       └── yml.ftl 
    ├── build.gradle  

Source code: the official account: bugstack wormhole stack reply: idea can download all the IDEA plug-in development source code.

In this IDEA plug-in project, it is mainly divided into five areas:

  • Domain: the domain layer, which provides services for creating DDD template projects. In fact, freemaker is mainly used in this part
  • factory: factory layer, which provides project creation templates. The role of this layer is to add our own content when we create a new project in the IDEA, that is, to create the DDD project structure we have defined.
  • infrastructure: the basic layer, which provides the functions of data storage, image loading and information mapping.
  • Module: the module layer provides specific operations and steps for creating DDD template projects, that is, when we create projects, we select them step by step. You can add your own step page as needed to allow users to select and add their own content. For example, you need to connect the library, select the table, add the technology stack required by the project, etc
  • UI: interface layer, which provides the UI interface developed by Swing for user graphical selection and creation.

2. UI project configuration form

public class ProjectConfigUI {

    private JPanel mainPanel;
    private JTextField groupIdField;
    private JTextField artifactIdField;
    private JTextField versionField;
    private JTextField packageField;

  • Use Swing UI Designer to create a UI form for configuring factory information, which can be directly dragged.
  • In this UI form, we mainly need; roupId,artifactId,version,package

3. Configuration engineering step creation

3.1 data storage

@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);

    public DataState getState() {
        return state;

    public void loadState(@NotNull DataState state) {
        this.state = state;

     public ProjectConfigVO getProjectConfig(){
        return state.getProjectConfigVO();

  • The data storage service is provided in the basic layer, and the configuration information of the creation project is stored in the service, which is more convenient to set and obtain.

3.2 expansion steps

public class DDDModuleConfigStep extends ModuleWizardStep {

    private ProjectConfigUI projectConfigUI;

    public DDDModuleConfigStep(ProjectConfigUI projectConfigUI) {
        this.projectConfigUI = projectConfigUI;

    public JComponent getComponent() {
        return projectConfigUI.getComponent();

    public boolean validate() throws ConfigurationException {
        // Get the configuration information and write it to DataSetting
        ProjectConfigVO projectConfig = DataSetting.getInstance().getProjectConfig();

        return super.validate();

  • Inherit ModuleWizardStep to develop a required step, which will appear in the new project we create.
  • At the same time, in the rewritten validate method, the information obtained from the project configuration UI form is written into the data configuration file.

3.3 configuration steps

public class DDDModuleBuilder extends ModuleBuilder {

    private IProjectGenerator projectGenerator = new ProjectGeneratorImpl();

    public Icon getNodeIcon() {
        return ICONS.SPRING_BOOT;
     * Override builderId to mount custom template
    public String getBuilderId() {
        return getClass().getName();
    public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {

        // Add project configuration steps. You can define the required steps by yourself. If there are multiple steps, you can add them in turn
        DDDModuleConfigStep moduleConfigStep = new DDDModuleConfigStep(new ProjectConfigUI());

        return new ModuleWizardStep[]{moduleConfigStep};
  • In the createWizardSteps method, add the DDDModuleConfigStep we have created to the project configuration step. You can define the required steps yourself. If there are multiple steps, you can add them in turn.
  • At the same time, it should be noted that the newly added wizard steps can only take effect after overriding the getBuilderId() method.

4. Develop scaffolding services

public abstract class AbstractProjectGenerator extends FreemarkerConfiguration implements IProjectGenerator {

    public void doGenerator(Project project, String entryPath, ProjectConfigVO projectConfig) {

        // 1. Create project main POM file
        generateProjectPOM(project, entryPath, projectConfig);

        // 2. Create a four tier architecture
        generateProjectDDD(project, entryPath, projectConfig);

        // 3. Create Application
        generateApplication(project, entryPath, projectConfig);

        // 4. Create Yml
        generateYml(project, entryPath, projectConfig);

        // 5. Create Common
        generateCommon(project, entryPath, projectConfig);

  • FreeMarker service for creating scaffold framework is added in the domain domain layer. It is a template engine: a general tool based on template and data to be changed, and used to generate output text (HTML web page, e-mail, configuration file, source code, etc.). FreeMarker online manual:
  • According to the DDD engineering structure, the hierarchy includes: application, domain, infrastructure and interfaces. Then we abstract these creation processes into the template method and give them to subclasses to create.

5. Call scaffold service

public class DDDModuleBuilder extends ModuleBuilder {

    private IProjectGenerator projectGenerator = new ProjectGeneratorImpl();

    public Icon getNodeIcon() {
        return ICONS.SPRING_BOOT;

    public void setupRootModel(@NotNull ModifiableRootModel rootModel) throws ConfigurationException {

        // Set JDK
        if (null != this.myJdk) {
        } else {

        // Generate project path
        String path = FileUtil.toSystemIndependentName(Objects.requireNonNull(getContentEntryPath()));
        new File(path).mkdirs();
        VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);

        Project project = rootModel.getProject();

        // Create engineering structure
        Runnable r = () -> new WriteCommandAction<VirtualFile>(project) {
            protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
                projectGenerator.doGenerator(project, getContentEntryPath(), DataSetting.getInstance().getProjectConfig());


  • In DDDModuleBuilder#setupRootModel, add the service for creating DDD project framework, projectGenerator.doGenerator(project, getContentEntryPath(), DataSetting.getInstance().getProjectConfig());
  • In addition, the thread calling method provided by IDEA is required here to create a new WriteCommandAction normally.

6. Configure formwork works

6.1 formwork factory

public class TemplateFactory extends ProjectTemplatesFactory {

    public String[] getGroups() {
        return new String[]{"DDD Scaffolding"};

    public Icon getGroupIcon(String group) {
        return ICONS.DDD;

    public ProjectTemplate[] createTemplates(@Nullable String group, WizardContext context) {
        return new ProjectTemplate[]{new BuilderBasedTemplate(new DDDModuleBuilder())};

  • The core of the template factory is to add the steps we used to create DDD to the createTemplates method, so that the whole link to create a custom scaffold project can be connected in series.

6.2 file configuration


    <vendor email="" url="https://Bugstack. CN "> little brother Fu < / vendor >

    <!-- please see
         on how to target different products -->

    <extensions defaultExtensionNs="com.intellij">
        <projectTemplatesFactory implementation=""/>
        <applicationService serviceImplementation=""/>

  • Next, we need to configure the project template and data service we created into plugin.xml, so that we can start our own plug-in when the plug-in starts.

4, Test verification

  • Click Plugin to start the IDEA plug-in, and then create the project as follows:

  • Take it and try it. Start the plug-in, click create project, and click fool to create a DDD project structure.

5, Summary

  • Learn to use the IDEA Plugin development technology, change the project creation wizard and add the project creation template you need, so that you can create a DDD scaffold project skeleton. Next, you can add some technology stacks you need to the scaffold in combination with your actual business scenario.
  • If you are willing to try, you can link to the database in the project creation and generate Java code from the corresponding tables in the database. In this way, you don't have to write some simple configuration, query and mapping yourself.
  • In developing the source code of DDD scaffold, there are some detailed processes, including the display of icons, the information of copywriting, and the use details of Freemarker, which you can learn, debug and verify in the source code.

6, Series recommendation

Posted by Arkane on Wed, 24 Nov 2021 16:08:34 -0800