一、背景
maven是一个很好的代码构建工具,采用“约定优先于配置”的原则进行项目管理,相信很多的java开发者应该都了解maven并可能在工作当中都是通过maven来管理项目的,在创建的项目的时候,我们往往会使用maven内置的项目骨架也就是archetype来快速生成项目结构。但是在一个团队做开发的过程中,可能仅仅依靠maven预先提供的archetyp可能是不够的,团队之间协作有自己的定义方式,每个人的结构定义风格也不尽相同,在这样的背景下我们有必要去定义一个统一的代码骨架供团队使用,这样做的好处是当团队需要开始一个新项目的时候,可以利用自定义的maven骨架一键生成项目。
简单来说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。
二、archetype 项目
archetype脚手架项目的结构:
概念说明:
-
- “__rootArtifactId__”占位符会被parent项目的artifactId替换
- ${rootArtifactId}也会被parent项目的artifactId替换
- src/main/resources/archetype-resources里必须要有一个顶级pom文件(如果是单工程就是工程pom文件),同时子文件夹代表了模块定义
上图中的各个文件详解:
-
- 根目录mcraft下的pom.xml和一般的maven项目一样主要定义archetype项目的坐标等信息。
- 所有的项目骨架内容都集中在src/main/resources/archetype-resources文件夹下。
- archetype-resources中的pom.xml定义了待生成项目的pom文件的内容,其他模板中分别定义了待生成项目中相应目录下的内容
- /src/main/resources/META-INF/maven/archetype-metadata.xml中定义相关的元数据描述(其中该文件的位置固定为resources/META-INF/maven文件夹下,且名称固定为archetype-metadata.xml)。
2.1 mcraft/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"> <modelVersion>4.0.0</modelVersion> <groupId>com.xxx</groupId> <artifactId>mcraft-archetype</artifactId> <version>1.0-SNAPSHOT</version> <name>mcraft-archetype</name> <distributionManagement> <repository> <id>local</id> <url>http://xxx.com/nexus/content/repositories/local/</url> </repository> <snapshotRepository> <id>local_snapshots</id> <url>http://xxx.com/nexus/content/repositories/local_snapshots/</url> </snapshotRepository> </distributionManagement> <repositories> <repository> <id>xxx-repos</id> <url>http://xxx.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>snapshots</id> <url>http://xxx.com/nexus/content/repositories/snapshots</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> <extensions> <extension> <groupId>org.apache.maven.archetype</groupId> <artifactId>archetype-packaging</artifactId> <version>3.0.1</version> </extension> </extensions> <pluginManagement> <plugins> <plugin> <artifactId>maven-archetype-plugin</artifactId> <version>3.0.1</version> </plugin> </plugins> </pluginManagement> </build> </project>
2.2 src/main/resources/META-INF/maven/archetype-metadata.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="demo-parent" xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <requiredProperties> <requiredProperty key="groupId"> <defaultValue>com.xxx</defaultValue> </requiredProperty> </requiredProperties> <modules> <module id="${rootArtifactId}-common" dir="__rootArtifactId__-common" name="${rootArtifactId}-common"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-dal" dir="__rootArtifactId__-dal" name="${rootArtifactId}-dal"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory></directory> <includes> <include>generatorConfig.xml</include> </includes> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-biz" dir="__rootArtifactId__-biz" name="${rootArtifactId}-biz"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-service-api" dir="__rootArtifactId__-service-api" name="${rootArtifactId}-service-api"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-service-impl" dir="__rootArtifactId__-service-impl" name="${rootArtifactId}-service-impl"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</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> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-job" dir="__rootArtifactId__-job" name="${rootArtifactId}-service-impl"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> </fileSets> </module> <module id="${rootArtifactId}-runner" dir="__rootArtifactId__-runner" name="${rootArtifactId}-runner"> <fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/main/java</directory> <includes> <include>**/*.java</include> </includes> </fileSet> <fileSet filtered="true" encoding="UTF-8"> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </fileSet> </fileSets> </module> </modules> </archetype-descriptor>
说明:
-
- packaged="true"标识src/main/resources/archetype-resources/src/main/java中对应的内容是否要放入到package中,比如package为com.xxx,那么如果该属性为true,则对应的java文件会放到com/xxx文件夹下,也就是包路径下。
- filtered="true"标识下面提到的${}是否要进行替换
属性变量定义:
<requiredProperties> <requiredProperty key="groupId"> <defaultValue>com.xxx</defaultValue> </requiredProperty> </requiredProperties>
这些属性可以在资源元文件里的任意一个文件里通过${var}来引用,所以的元文件最终都可以选择通过velocity引擎来执行替换后生成。
默认的属性有:groupId,artifactId,packeage,version等
项目子模块定义:
<modules > <module id="${rootArtifactId}-common" dir="__rootArtifactId__-common" name="${rootArtifactId}-common"> ... </module> ... </modules>
module有三个属性,解释如下:
id :定义子模块工程的artifactId.
dir :子模块工程源文件在archetype-resources里对应的directory.
name :子模块的名字.
2.3 通过mvn clean install 命令把该jar包安装到本地仓库,然后通过本地仓库中的该jar包来生成一个项目看看效果,使用如下命令:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4::generate -DartifactId=demo -DarchetypeArtifactId=mcraft-archetype -DarchetypeVersion=1.0-SNAPSHOT -DarchetypeGroupId=com.xxx -DarchetypeCatalog=local