Maven-自定义工程骨架archetype

流过昼夜 提交于 2020-01-06 20:55:19

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

简介

再成熟的开发体系中,为统一团队的工程结构,规范管理,提供工程结构模块划分的经验分享和落地,采用maven的工程骨架技术实现是比较优选的方案。本文以实际工作为基础,介绍acooly团队中maven-archetype的规划和开发情况,记录和传递。

在网上搜索很多内容,对archetype的开发这块都比较凌乱,自己团队强需求的情况下,完整做了一遍,解决了一些不好找答案的问题,对半还是来自官方文档(不详细啊)和YY方式的尝试。本文将回答一直困扰我的以下问题:

  • 从模板工程创建archetype时,怎么配置需要忽略的文件或文件夹? -> excludePatterns
  • 从模板工程创建archetype时,怎么配置需要进行velocity渲染的扩展名? -> archetype.filteredExtensions
  • 怎么风sao的自定义参数? 定义,解析,模板语言操作,生成工程时传入等 -> 看我便知了
  • 怎么让别人好用? -> 友好的命令行工具。

工程骨架开发

模板工程

在开始介绍前,开发者需要先手动创建一个目标工程结构的模板工程,然后根据这个工程来创建archetype会事半功倍,也是本文推荐的方式。本文以一个多模块工程作为demo介绍。工程结构如下:

+ acooly-allinone			 工程项目名称	  
	+ assemble                  整合打包和配置
	+ common                    公共结构和工具
	+ facade                    微服务接口定义
	+ platform                  业务模块
	+ test                      单元测试

注意:请保证该工程能力正常运行,并是按你的期望设计的工程结构,默认配置。后期通过archetype生成的工程应该与该模块工程结构和能力一致。

创建archetype工程

采用:create-from-project方式。

配置文件

在模板工程acooly-allinone的根目录下新建配置文件:archetype.properties,并写入该工程的配置信息参与,用于后面根据该模板工程创建archetype工程。

archetype.properties中定义的参数会在整个模板工程(acooly-allinone)中,解析和目录及文件查找参数值替换为${key}的模式,用于在客户通过archetype:generate时,动态根据客户的参数替换。

archetype.properties:

groupId=com.acooly.app
artifactId=acooly-allinone
version=1.0-SNAPSHOT
package=com.acooly.app.allinone
# 需要忽略的文件
excludePatterns=/**/*.iml,/.idea/**/*,/**/*.sh
# 需要采用template解析和替换本配置文件定义的参数的文件
archetype.filteredExtensions=java,sql,properties,factories,ftl

# 如有需要,可定义其他自定义参数

生成archetype

以上设置OK后,我们使用下面的命令来生成archetype工程。

mvn clean archetype:create-from-project -Darchetype.properties=archetype.properties

如果你没有配置maven的settings.xml的默认参数,请手动指定该命令使用的环境设置配置文件,例如:/Users/zhangpu/software/apache-maven-3.3.9/conf/settings-acooly.xml , 则命令如下:

mvn clean archetype:create-from-project -Darchetype.properties=archetype.properties \
 -s /Users/zhangpu/software/apache-maven-3.3.9/conf/settings-acooly.xml

如果以上命令执行成功,则会在模板工程目录下产生target目录,请进行一下操作。

# 进入archetype源代码模块,查看生成的archetype工程。
cd target/generated-sources/archetype
ll
-rw-r--r--  1 zhangpu  staff  2546 Jan  5 19:02 pom.xml
drwxr-xr-x  4 zhangpu  staff   128 Jan  5 19:02 src
drwxr-xr-x  5 zhangpu  staff   160 Jan  5 19:02 target

配置调整

在生产工程后,可根据自定义需要进行一下常用的配置和调整。在开始前,确保你通过create-from-project方式生成的基础archetype工程完整和正确后,建议你拷贝生成的archetype源代码(target/generated-sources/archetype下)到新的工程目录,独立管理(包括提交到git等进行版本管理),后续的操作都可以在此代码基础上进行操作。

Archetype的GAV

最基础的,你需要定义你创造的archetype的GAV坐标。打开源代码目录中的pom.xml,调整GAV坐标。

配置文件:pom.xml

  ...
  <groupId>com.acooly.app</groupId>
  <artifactId>acooly-allinone-archetype</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>maven-archetype</packaging>
  <name>acooly-allinone-archetype</name>
  ...

以上配置打包或发布后的maven-archetype的则为:com.acooly.app:acooly-allinone-archetype 1.0-SNAPSHOT

ArcheType名称

配置文件:archetype-metadata.xml

在archetype-metadata.xml配置文件的根节点archetype-descriptor上修改name属性为你喜欢的名字,这个名字一般用于在catalog(IDE等列表中)列表中显示的名称。建议直接采用GAV的artifactId。

自定义参数

配置文件:archetype-metadata.xml

如果你希望在工程的使用自定义参数,可以通过src/main/resources/META-INF/maven/archetype-metadata.xml配置文件进行跳转。关于archetype-metadata.xml的规范,请参考附件。

在archetype-metadata.xml文件的根元素下(与fileSets同级),增加自定义参数配置。

    <requiredProperties>
        <requiredProperty key="author">
            <defaultValue>acooly</defaultValue>
        </requiredProperty>
        <requiredProperty key="webport">
            <defaultValue>8080</defaultValue>
        </requiredProperty>
        <requiredProperty key="mysqlHost">
            <defaultValue>127.0.0.1</defaultValue>
        </requiredProperty>
        <requiredProperty key="mysqUserName">
            <defaultValue>root</defaultValue>
        </requiredProperty>
        <requiredProperty key="mysqlPassword">
            <defaultValue>123456</defaultValue>
        </requiredProperty>
    </requiredProperties>

	<fileSets>
		...
	</fileSets>	

所有自定义参数都可以像内置参数一样,在工程内文件中进行velocity template方式替换。例如,可以再archetype中内置对application.properties的修改,如下:

acooly.ds.url=jdbc:mysql://${mysqlHost}:3306/${parentArtifactId}
acooly.ds.username=${mysqUserName}
acooly.ds.password=${mysqlPassword}

以上配置的参数,必须配置默认参数,并且不能在generate工程时交互式设置,只能通过-D方式参数传入,例如:

mvn archetype:generate -Dauthor=zhangpu -D webport=8089 \
    -DarchetypeGroupId=com.acooly.app  \
    -DarchetypeArtifactId=acooly-allinone-archetype \
    -DarchetypeVersion=1.0-SNAPSHOT \
    -s /Users/zhangpu/software/apache-maven-3.3.9/conf/settings-acooly.xml

技巧:如上面的命令,如果自定义参数在命令行中有传入,但值为空(-Dauthor=),则会启动maven的交互模式,与内置参数一样,后面会提示你输入author参数。

注意:如果打包(install deploy等)时,报错说:没有在archetype.properties定义你定义的自定义属性。Missing required properties in archetype.properties: ,是因为集成测试模块造成,请在src/test/resources/projects/basic/archetype.properties中添加对应的属性即可解决。

参数渲染

maven-archetype的模板渲染采用的是velocity(有点老,个人好多年不用,已不熟悉了),考虑部分内置的java类或配置,需要定制,比如:部分类名称希望采用工程名称作为前缀,但是工程名字(一般是rootArtifactId)可能存在-分割(例如:acooly-allinone-demo),那么希望采用工程的最后一个-的后面部分作为类前缀,所以需要采用velocity对字符串进行处理。在所有可渲染的文件中(你最初设置的archetype.filteredExtensions=java,sql,properties,factories,ftl),你都可以使用velocity语法对变量和内容进行处理。

例如:获取rootArtifactId的最后一部分作为系统名称。

CommonProperties.java

// ...

#set( $systemName = ${rootArtifactId} )
#if(${rootArtifactId.indexOf("-")}!=-1)
    #set( $cc = ${rootArtifactId.split("-")})
    #if($cc != $null && ${cc.size()} > 0)
        #set( $lastIndex = $cc.size() - 1 )
        #set( $systemName = $cc[$lastIndex] )
    #end
#end

@ConfigurationProperties("${systemName}")
@Data
public class CommonProperties {
	// ...
}

本地发布和测试

在archetype源代码根目录,运行命令。

# 本地发布,并更新local-catalogs
mvn install

# 测试
mkdir test
cd test

# 从本地catalog中选择刚才发布的archetype生成工程,注意,这种方式是交互模式,无法更新自定义参数的值。
# 如果需要传入自定义参数的值,请采用命令行-D方式传入。
mvn archetype:generate -DarchetypeCatalog=local

注意:这里不用增加-s参数指定settings配置,因为在create-from-project时,已拷贝相关配置到archetype的pom.xml文件中。如果你对pom.xml进行了调整(比如整合到你现有的基础技术体系),需要考虑当前运行名命令的settings 环境。

远程发布

本地测试OK后,可远程发布到你的仓库。因IDE和仓库catalog的能力不确定,建议编写命令行工具,让团队可统一使用。

mvn deploy

参考文档

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!