一、背景

  maven是一个很好的代码构建工具,采用“约定优先于配置”的原则进行项目管理,相信很多的java开发者应该都了解maven并可能在工作当中都是通过maven来管理项目的,在创建的项目的时候,我们往往会使用maven内置的项目骨架也就是archetype来快速生成项目结构。但是在一个团队做开发的过程中,可能仅仅依靠maven预先提供的archetyp可能是不够的,团队之间协作有自己的定义方式,每个人的结构定义风格也不尽相同,在这样的背景下我们有必要去定义一个统一的代码骨架供团队使用,这样做的好处是当团队需要开始一个新项目的时候,可以利用自定义的maven骨架一键生成项目。

  archetype是在maven-archetype-plugin插件执行generate目标的时候进行配置的,我们经常使用到maven的内嵌的骨架包括:maven-archetype-webapp、maven-archetype-quickstart。前者用来快速搭建一个web工程项目,后者用来快速搭建一个普通的java工程项目。

二、手写普通单模块项目的archetype

单模块项目的archetype脚手架项目的结构

  

上图中的各个文件详解:

  • 根目录beast-archetype下的pom.xml和一般的maven项目一样主要定义archetype项目的坐标等信息。
  • 所有的项目骨架内容都集中在src/main/resources/archetype-resources文件夹下。
  • archetype-resources中的pom.xml定义了待生成项目的pom文件的内容,/src/main/java、/src/test/java中分别定义了待生成项目中相应目录下的内容
  • /src/main/resources/META-INF/maven/archetype-metadata.xml中定义相关的元数据描述(其中该文件的位置固定为resources/META-INF/maven文件夹下,且名称固定为archetype-metadata.xml)。

1.beast-archetype/pom.xml内容如下

<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.thebeastshop</groupId>
<artifactId>beast-archetype</artifactId>
<version>1.1</version>
<packaging>jar</packaging> <name>beast-archetype</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>beast-archetype</finalName>
</build>
</project>

2.src/main/resources/archetype-resources/pom.xml内容如下:

<?xml version="1.0"?>
<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>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<name>${artifactId}</name> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>2.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

其中:上面${}标识的变量都是通过maven中的命令行传进来的,如:mvn archetype:generate -DgroupId=com.thebeastshop

3.src/main/resources/META-INF/maven/archetype-metadata.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="beast-archetype"
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> <requiredProperties>
<requiredProperty key="package-name" />
</requiredProperties> <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>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/test/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</archetype-descriptor>

说明:

  • packaged="true"标识src/main/resources/archetype-resources/src/main/java中对应的内容是否要放入到package中,比如package为com.thebeastshop,那么如果该属性为true,则对应的java文件会放到com/thebeastshop文件夹下,也就是包路径下。
  • filtered="true"标识下面提到的${}是否要进行替换

4.src/main/resources/archetype-resources/src/main/java/Demo.java内容如下:

package ${package};

public class Demo{
public static void main( String[] args )
{
System.out.println( "Hello My Archetype!" );
}
}

5.这样我们就手写好了一个自定义的maven的archetype骨架项目,我们只需要通过mvn clean install 命令把该jar包安装到本地仓库,然后通过本地仓库中的该jar包来生成一个项目看看效果,使用如下命令:

 mvn archetype:generate 
  -DgroupId=comthebeastshop
  -DartifactId=beast-test
  -Dpackage="com.thebeastshop.test"
  -DarchetypeGroupId=com.thebeastshop
  -DarchetypeArtifactId=beast-archetype -DarchetypeVersion=1.1 -X -DarchetypeCatalog=local

三、手写maven多module的项目骨架archetype

1.多模块骨架项目的项目结构

这跟单模块项目区别不大,但是有几个概念需要说明:

  • “__rootArtifactId__”占位符会被parent项目的artifactId替换
  • ${rootArtifactId}也会被parent项目的artifactId替换
  • src/main/resources/archetype-resources里必须要有一个顶级pom文件(如果是单工程就是工程pom文件),同时子文件夹代表了模块定义

2.模板工程定义描述文件:META-INF/maven/archetype-metadata.xml

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="beast-archetype"
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> <requiredProperties>
<requiredProperty key="groupId">
<defaultValue>com.thebeastshop</defaultValue>
</requiredProperty>
<requiredProperty key="artifactId">
<defaultValue>test</defaultValue>
</requiredProperty>
<requiredProperty key="package">
<defaultValue>com.thebeastshop.test</defaultValue>
</requiredProperty>
</requiredProperties> <modules>
<module id="${rootArtifactId}-api" name="${rootArtifactId}-api" dir="__rootArtifactId__-api">
<fileSets>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/test/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-core" name="${rootArtifactId}-core" dir="__rootArtifactId__-core">
<fileSets>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/test/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-dao" name="${rootArtifactId}-dao" dir="__rootArtifactId__-dao">
<fileSets>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/test/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
<include>mapper</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-main" name="${rootArtifactId}-main" dir="__rootArtifactId__-main">
<fileSets>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/test/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/main/assembly</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/main/bin</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-mybatisGen" name="${rootArtifactId}-mybatisGen" dir="__rootArtifactId__-mybatisGen">
<fileSets>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8" packaged="true">
<directory>src/test/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/test/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</module>
</modules>
</archetype-descriptor>
  • 属性变量定义
  • <requiredProperties>
    <requiredProperty key="groupId">
    <defaultValue>com.thebeastshop</defaultValue>
    </requiredProperty>
    <requiredProperty key="artifactId">
    <defaultValue>test</defaultValue>
    </requiredProperty>
    <requiredProperty key="package">
    <defaultValue>com.thebeastshop.test</defaultValue>
    </requiredProperty>
    </requiredProperties>

    这些属性可以在资源元文件里的任意一个文件里通过${var}来引用,所以的元文件最终都可以选择通过velocity引擎来执行替换后生成。
    默认的属性有:groupId,artifactId,packeage,version等

  • 项目子模块定义
    <modules>
    <module id="${rootArtifactId}-api" name="${rootArtifactId}-api" dir="__rootArtifactId__-api">
    ...
    </module>
    <module id="${rootArtifactId}-core" name="${rootArtifactId}-core" dir="__rootArtifactId__-core">
    ...
    </module>
    <module id="${rootArtifactId}-dao" name="${rootArtifactId}-dao" dir="__rootArtifactId__-dao">
    ...
    </module>
    <module id="${rootArtifactId}-main" name="${rootArtifactId}-main" dir="__rootArtifactId__-main">
    ...
    </module>
    <module id="${rootArtifactId}-mybatisGen" name="${rootArtifactId}-mybatisGen" dir="__rootArtifactId__-mybatisGen">
    ...
    </module>
    </modules>

    module有三个属性,解释如下:
    id     :定义子模块工程的artifactId.
    dir    :子模块工程源文件在archetype-resources里对应的directory.
    name   :子模块的名字.

3.子模块pom.xml定义如下(以core模块为例):

<?xml version="1.0"?>
<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>
<parent>
<groupId>com.thebeastshop</groupId>
<artifactId>${rootArtifactId}</artifactId>
<version>${version}</version>
</parent> <artifactId>${artifactId}</artifactId>
<name>${artifactId}</name> <dependencies>
<dependency>
<groupId>com.thebeastshop</groupId>
<artifactId>${rootArtifactId}-api</artifactId>
<version>${api.version}</version>
</dependency>
<dependency>
<groupId>com.thebeastshop</groupId>
<artifactId>${rootArtifactId}-dao</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

其中${rootArtifactId}就代表父项目的artifactId.

4.我们和单模块脚手架工程一样,通过mvn clean install命令把该脚手架项目安装到本地maven仓库,然后就可以使用该项目来快速生成新项目结构了,生成命令如下:

mvn archetype:generate 
  -DgroupId=com.thebeastshop
  -DartifactId=ddd
  -Dversion=1.0.0-SNAPSHOT
  -DarchetypeGroupId=com.thebeastshop
  -DarchetypeArtifactId=beast-archetype
  -DarchetypeVersion=1.3-SNAPSHOT -X -DarchetypeCatalog=local

我们就会看到生成好的项目结构如下:

多模块项目脚手架源码:https://github.com/hafizzhang/beast-archetype

四、总结

  在工作中,我们通常要有“偷懒”意识,通过摸索来开发出类似项目脚手架一样的工具来提升自己工作的效率。不能整天都是浑浑噩噩的过去,而且表面上看上去很难的东西实际上并不见得一定就如想象中的难。程序猿还是要有所追求,哈哈~

手写Maven的archetype项目脚手架的更多相关文章

  1. 创建maven自定义archetype项目

    1.安装Nexus这里是用homebrew安装, brew nexus 安装成功后,默认的访问端口为8081, 我这里的访问地址是http://192.168.99.100:8081 默认用户:adm ...

  2. 【深度学习系列】手写数字识别卷积神经--卷积神经网络CNN原理详解(一)

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  3. TensorFlow实战之Softmax Regression识别手写数字

         关于本文说明,本人原博客地址位于http://blog.csdn.net/qq_37608890,本文来自笔者于2018年02月21日 23:10:04所撰写内容(http://blog.c ...

  4. 自定义项目脚手架- Maven Archetypes

    在上篇Intellij修改archetype Plugin配置 中我们已经简单介绍了关于archetype的作用. 简单来说maven archetype插件就是创建项目的脚手架,你可以通过命令行或者 ...

  5. 纯手写SpringMVC到SpringBoot框架项目实战

    引言 Spring Boot其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 通过这种方式,springboot ...

  6. 基于maven的项目脚手架,一键创建项目的项目模板

    制作基于maven的项目脚手架 Springboot的出现极大的简化了项目开发的配置,然而,到真实使用的时候还是会有一堆配置需要设定.比如依赖管理,各种插件,质量扫描配置,docker配置,持续集成配 ...

  7. SpringBoot项目里,让TKmybatis支持可以手写sql的Mapper.xml文件

    SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里 ...

  8. 【开源项目】Android 手写记事 App(半成品)

    该项目已上传到 CSDN 的 Git 平台中 项目地址:https://code.csdn.net/gd920129/whiteboard GIT SSH:git@code.csdn.net:gd92 ...

  9. Linux使用IDEA配置maven的web项目骨架archetype(模板) 自定义骨架

    说明:本文说的骨架就是 archetype,也可以理解为模板,总是就是指你创建项目时的基本配置. 前言:在使用IDEA创建maven的web项目时,一般都是直接使用提供的默认web项目,如图 然而创建 ...

随机推荐

  1. Entity Framework Core 2.0 全局查询过滤器

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunnarpeipman.com/2017/08/ef ...

  2. struts2的java.lang.NoSuchMethodException异常处理(转)

    不久前在学习struts时出现这个错误,在网上搜索了半天,发现答案不一.将其总结如下,以方便大家参考. 1. 你有没有试试看 其它的方法能不能用,要是都是这种情况的话,可能是你的Action类没有继承 ...

  3. How to quickly become effective when joining a new company

    How to quickly become effective when joining a new company The other day my colleague Richard asked ...

  4. vue2项目使用axios发送请求

    前言:在Vue1.0的时候有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource. 目前主流的 Vue 项目,都选 ...

  5. mysql 常用函数总结

    常用处理函数: mysql_connect(server,user,pwd,newlink,clientflag) 连接服务器的函数,成功则返回MySQL标识,失败则返回FALSE mysql_sel ...

  6. ASP.NET Core MVC – Tag Helper 组件

    ASP.NET Core Tag Helpers系列目录,这是第五篇,共五篇: ASP.NET Core MVC – Tag Helpers 介绍 ASP.NET Core MVC – Caching ...

  7. 003-0.6632是float/Float/double/Double中的哪个?

    应该是float,最后两个是包装类,这里应该安装基本类型去看待. 而java的浮点型默认是double型,如果希望生成一个float型的浮点数则需要在这个值的后面紧跟f和F.

  8. node.js后台快速搭建在阿里云(一)(express篇)

    前期准备 阿里云服务器 node.js pm2 express nginx linux(推荐教程:鸟哥的私房菜) 简介 嗯……我只是个前端而已 前段时间写过一个.net mvc的远程发布,关于.net ...

  9. hibernate的基本配置

    1   Hibernate是一个非侵入式的ORMapping的框架. 2   Hibernate是一个能够将JAVA对象  通过   映射关系    映射到   关系型数据库的  这样一个框架 Hib ...

  10. ASP.NET Core Razor 视图组件

    视图组件简介 在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大.视图组件不使用模型绑定,仅依赖于您在调用时提供的数据. 视图组件特性: 呈现页面响应的某一部分而不是整个响 ...