【推荐】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