手写Maven的archetype项目脚手架

一、背景

  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

四、总结

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

时间: 2024-08-05 06:58:36

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

BP神经网络识别手写数字项目解析及代码

这两天在学习人工神经网络,用传统神经网络结构做了一个识别手写数字的小项目作为练手.点滴收获与思考,想跟大家分享一下,欢迎指教,共同进步. 平常说的BP神经网络指传统的人工神经网络,相比于卷积神经网络(CNN)来说要简单些. 人工神经网络具有复杂模式和进行联想.推理记忆的功能, 它是解决某些传统方法所无法解决的问题的有力工具.目前, 它日益受到重视, 同时其他学科的发展, 为其提供了更大的机会.1986 年, Romelhart 和Mcclelland提出了误差反向传播算法(Error Back

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

     关于本文说明,本人原博客地址位于http://blog.csdn.net/qq_37608890,本文来自笔者于2018年02月21日 23:10:04所撰写内容(http://blog.csdn.net/qq_37608890/article/details/79343860).        本文根据最近学习TensorFlow书籍网络文章的情况,特将一些学习心得做了总结,详情如下.如有不当之处,请各位大拿多多指点,在此谢过. 一.相关概念 1.MNIST MNIST(Mixed

springboot项目里,让tk-mybatis支持可以手写sql的mapper.xml文件

SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里定义sql. 我们目前的项目呢,有一些数据分析的需求,涉及到多表关联.嵌套子查询等复杂的sql. 那么,TKMybatis是不是可以支持手写sql呢? 答案是yes! 我们知道,springboot集成tk-mybatis需添加2个依赖: <dependency> <groupId>t

Android手写开源项目和资料搜集

引言 Android的手写效率一直是件头疼的事情,比如手写效率.笔锋效果.手掌抑制等等,本文搜集了关于手写的开源项目和一些相关的文章资料. 开源项目 1 android-signaturepad 项目地址:android-signaturepad 项目介绍:这是一款银行手写签名的应用,通过event的getHistory方法获取存储在MotionEvent中的历史点,大大提高了手写的流畅度,通过算法实现了笔锋效果. 2  Markers 项目地址:Markers 项目介绍:这是一款带有笔锋效果的

利用手写数字识别项目详细描述BP深度神经网络的权重学习

本篇文章是针对学习<深度学习入门>(由日本学者斋藤康毅所著陆羽杰所译)中关于神经网络的学习一章来总结归纳一些收获. 本书提出神经网络的学习分四步:1.mini-batch 2.计算梯度 3.更新参数 4.重复前面步骤 1.从识别手写数字项目学习神经网络 所谓“从数据中学习”是指 可以由数据#自动决定权重#.当解决较为简单的问题,使用简单的神经网络时,网络里的权重可以人为的手动设置,去提取输入信息中特定的特征.但是在实际的神经网络中,参数往往是成千上万,甚至可能上亿的权重,这个时候人为手动设置是

pytorch 手写数字识别项目 增量式训练

dataset.py ''' 准备数据集 ''' import torch from torch.utils.data import DataLoader from torchvision.datasets import MNIST from torchvision.transforms import ToTensor,Compose,Normalize import torchvision import config def mnist_dataset(train): func = torch

如何使用Maven的archetype快速生成一个新项目(解决生成项目目录不完整问题)

Maven的archetype Plugin可能大家都听过,但不一定都能很好地用好它.缺省地如果你使用 mvn archetype:generate 会从maven的Repository里查找所有支持的arche types,大概有500~600个.正因为是太多了,所以查找起来很是不方便. 其实平时常用的arche type也就那么几个.像我会用到的: 1.simple start 2. web app 3. Groovy basic 很自然的就会考虑,是不是能什么简便的方法只需要从这3个组成的

android项目 之 记事本(15) ----- 保存手写及绘图

本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 之前,忘了写如何将手写和绘图保存,现在补上. 首先看如何保存绘图,先看效果图: 因为记事本的绘图功能主要用到了画布,而在构建画布时,指定了Bitmap,也就是说在画布上的所画的东西都被保存在了Bitmap中,因此,我们只要保存该Bitmap,就可以将我们的所绘制的图形以图片的形式保存,主要代码如下: /* * 保存所绘图形 * 返回绘图文件的存储路径 * */ public S

android项目 之 记事本(7)----- 手写功能之删除、恢复和清空

上一节,为记事本添加了手写的功能,但是没有实现底部按钮的各种功能,这节就先实现撤销,恢复和清空的功用. 因为不会录制屏幕成gif图片,所以就以图片形式给出吧,不是很形象,凑合着看: 显然,需要为底部GridView的添加item单击事件: private GridView paint_bottomMenu; paint_bottomMenu = (GridView)findViewById(R.id.paintBottomMenu); paint_bottomMenu.setOnItemClic