基于maven-archetype自定义项目脚手架

开发中,我们通常会使用maven内置的脚手架也就是archetype来快速生成项目结构。但是在开发中,你会发现maven预先提供的archetyp远远不够,每次新建一个项目,我们都需要从现有的项目copy pom.xml,spring的配置文件,一些公共的工具类等,对于多module项目,我们还需要去创建各个module。在这样的背景下,我们就需要使用maven的archetype去定义一个自己想要的代码脚手架以供更快的生成新的项目骨架,可以进行后续开发。

简单来说maven archetype插件就是创建项目的脚手架,你可以通过命令行或者IDE集成简化项目创建的工作。例如:

  • org.apache.maven.archetypes:maven-archetype-quickstart
  • org.apache.maven.archetypes:maven-archetype-site
  • org.apache.maven.archetypes:maven-archetype-webapp
  • 以及spring或者第三方提供了一些archetype plugin

同时maven archetype插件也是一个简单的maven artifact,它包含了创建项目所需要的所有资源。 主要分为几类原型信息:

  • archetype描述文件src/main/resources/META-INF/maven/archetype.xml,这为archetype 1.0, 包含所有创建项目的文件信息和路径信息。 archetype 2.0 增加了更灵活的archetype-metadata.xml(src/main/resources/META-INF/maven/, archetype元数据信息,并且完全支持1.0
  • 项目的原型文件:位于src/main/resources/archetype-resources/之下,将会被archetype插件复制到项目目录结构去,这一部分是定义脚手架的核心模块。
  • 创建项目的pom文件:位于src/main/resources/archetype-resources下,用于给原型文件设置pom依赖
  • archetype pom文件:在archetype项目根目录下,这个是整个archetype的pom文件,和原型文件pom依赖不是一个概念,注意这里不要混淆!

一、基于archetype插件创建项目脚手架

1.首先在archetype中加入一个pom文件,如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.github.greengerong</groupId>
      <artifactId>component</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>

      <name>component</name>
      <url>http://maven.apache.org</url>

      <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>

      <dependencies>
      </dependencies>
</project>

2.在src/main/resources/META-INF/maven/目录下创建archetype-metadata.xml,例如:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor xsi:schemaLocation="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0 http://maven.apache.org/xsd/archetype-descriptor-1.1.0.xsd" name="ibu-itinerary-archetype"
                      xmlns="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!--属性变量定义:
  requiredProperty:定义通过archetype生成项目时需要提供的参数,这些属性可以在资源元文件里的任意一个文件里通过${var}来引用,所以的元文件最终都可以选择通过velocity引擎来执行替换后生成。
  默认的属性有:groupId,artifactId,packeage,version等
  -->
  <requiredProperties>
    <requiredProperty key="package">
      <defaultValue>top.easyboot.titan</defaultValue>
    </requiredProperty>
  </requiredProperties>
  
  <!--项目子模块定义:
  module 定义子模块
    1) id :定义子模块工程的artifactId
    2) dir  :定义子模块源文件在archetype-resources里对应的directory
    3) name :定义子模块的名字
  -->
  <modules>
    <module id="${rootArtifactId}-common" dir="__rootArtifactId__-common" name="${rootArtifactId}-common">
      <fileSets>
	  <!--
	  fileSet:定义通过Archetype插件生成的项目里的文件和脚手架jar里的文件的关联关系

		1) packaged="true"标识directory中对应的内容是否要放入到package中,比如package为top.easyboot,那么如果该属性为true,则对应的java文件会放到top/easyboot文件夹下,也就是包路径下。

		2) filtered="true"标识下面提到的${}是否要进行替换
	  -->
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
    <module id="${rootArtifactId}-core" dir="__rootArtifactId__-core" name="${rootArtifactId}-core">
      <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
    <module id="${rootArtifactId}-web" dir="__rootArtifactId__-web" name="${rootArtifactId}-web">
      <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
  </modules>
</archetype-descriptor>

3.创建对应的子模块下的pom.xml和java文件,可以使用${artifactId} / ${groupId} 等变量作为占位符,以core模块为例:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>${rootArtifactId}</artifactId>
        <groupId>${groupId}</groupId>
        <version>${version}</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
 
    <artifactId>${artifactId}</artifactId>
 
    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
   </dependencies>
 
</project>

DemoService.java

package ${packge}.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ${packge}.dao.client.mapper.DemoMapper;

@Slf4j
@Service
public class DemoService {

   @AutoWaire
   private DemoMapper demoMapper;
   
   pulbic Example getExample(){
       return demoMapper.getExample();
   }

}

整个项目的结构如下:

archetype项目写好之后,通过mvn clean install命令安装到本地的maven仓库中:

这条命令的作用是,将刚才创建的骨架,安装到maven本地的repository目录下。 如果在本地安装的Maven没有更改里面的 localRepository 地址的话,那么本地repository仓库的路径默认就在 c:\User\{USER-NAME}\.m2\repository , 找到该文件夹,应该能在里面找到以archetype命名的文件夹:

接下来,要让maven能够找到该项目并且知道它是个骨架项目。执行命令 mvn:archetype:crawl。 因为仅安装到本地仓库中,maven还是没有更新所有骨架的列表,所以该命令,能够让maven对本地仓库中所有项目进行一次遍历,并且找到其中可以作为 archetype的的项目,将这些信息保存到仓库下的 archetype-catalog.xml文件中。

由于 mvn archetype:crawl 执行命令的图太长,我这里就不贴了。 执行完后也能看到如上图中显示 的 BUILD SUCESS 字样。

二、基于已有的项目结构生成archetype

在项目的根目录下(即项目的pom.xml文件所在目录)下执行maven命令: mvn archetype:create-from-project

等待Maven构建,构建成功之后生成的archetype的信息,默认是在project根目录下的 target\generated-sources\archetype 目录。

执行命令成功之后,打开 target\generated-sources\archetype 将模块名修改成如下样式(只有一个模块跳过此步骤)

并且对应修改 archetype-metadata.xml 文件中的modules模块,参数名称含义参考第一节

然后在archetype的根目录下(\target\generated-sources\archetype)执行mvn clean install命令就可以将archetype安装在本地仓库里了,之后任然需要执行 mvn:archetype:crawl 命令。

三、使用archetype构建新项目

上面介绍了两种自定义项目archetype的方式,构建成功之后我们也可以有两种方式来使用构建成功的脚手架来建立新项目:

3.1 使用命令行

在空白目录下执行如下命令:

mvn archetype:generate -DarchetypeGroupId=<archetype-groupId>  -DarchetypeArtifactId=<archetype-artifactId> -DarchetypeVersion=<archetype-version>  -DgroupId=<my.groupid> -DartifactId=<my-artifactId>

具体参数含义:

  • -DarchetypeGroupId: GroupId
  • -DarchetypeArtifactId: ArtifactId
  • -DarchetypeVersion: Version
  • -DgroupId: groupId

3.2 使用图形化界面创建

(1)在IDEA中,新建项目时选择【Maven】,然后再选择 Create from archetype,选择 Add Archetype...

(2)在Add Archetype... 对话框中添加对应脚手架的 GroupIdArtifactIdVersion

如果添加发现没有作用,这时候需要去 C:/Users/[你的用户名]/AppData/Local/JetBrains/IntelliJIdea2021.2/Maven/Indices 目录下,创建一个 UserArchetypes.xml 文件,内容参考如下:

<archetypes>
   <archetype groupId="你的项目groupId" artifactId="你的项目名称" version="项目版本" />
</archetypes>

然后重启一波 IDEA,新建模块,这时候就会发现原型列表中出现了我们自定义的脚手架:

(3) 新建项目

选择archetype,然后填写新项目的GroupIdArtifactIdVersion

(4)等待Maven根据archetype初始化项目

留言区

还能输入500个字符