archetype是什么
archetype是maven的工程原型(模版),也就是说,使用archetype,可以将maven中已存在的工程结构和配置套用到新创建的工程上。
一般用idea创建maven工程的时候,大家也都是这样做的。
但是可能我们会觉得,idea提供的原型,太简单了,配置还是太少,这个时候我们就可以自己创建archetype,然后加到maven中,供自己和其他人使用
如何创建archetype(简易版,标准版请看后面#更多问题)
第一步
首先,是要创建供其他工程使用的模版工程,比如SSM的框架,包的结构等
第二步
然后,将该模版工程创建成archetype,这里要用到mvn的命令,在项目根目录下运行:
mvn archetype:create-from-project
maven会打包工程,生成target文件夹和对应的包
这里需要注意的问题是,在idea中,可能需要删除idea生成的.idea
文件夹和*.iml
文件,以防止利用工程原型创建工程和原型之间冲突
第三步
最后,进入到target\generated-sources\archetype文件夹下,通过命令mvn install
将工程原型安装到本地,或者通过mvn deploy
将工程原型发布。
如何使用archetype
如果是在idea增加的话,可以在创建新工程的时候选择add archetype加入,需要注意的是,其中Artfactid是自己创建的工程原型+-archetype
如果是使用maven命令行,则可以通过mvn archetype:generate
按提示选择
更多问题
上面其实是个个人适用简易版的创建方法,标准一点的,需要考虑如下问题:
1. 项目层级结构中空包的问题:maven默认不会将空包打包
2. archetype的配置文件:官方一点,一定有一个描述和配置的文件
3. 各级包名的命名问题:你一定不会像让所有工程都和工程原型一样的包名
对于第一个问题,需要做的是修改maven插件配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- 增加这一句 -->
<includeEmptyDirs>true</includeEmptyDirs>
</configuration>
</plugin>
第二个问题,当我们通过mvn archetype
命令生成工程原型的时候,maven会帮我们创建一个原型的说明文件,在target\generated-sources\archetype\target\classes\META-INF\maven
目录下,不过可能我们想自己修改
对于第三个问题,比较复杂,涉及一点原理,maven archetype其实是在新工程创建完成后,在新工程内,再创建工程原型里有的各种文件的,所以如果重命名报名,就需要通过占位符在包名上占位留空,对应的,类的package 也需要占位符。
这里的占位符其实是指maven的变量,其中groupId、artifactId都是maven工程的变量,原则上包名,类里的package直接拿来用就成。但是groupId默认是.
分割的,而包是文件夹,是通过\
分割的,所以直接用groupId还不行,查一查,搜一搜,我们发现,有packageInPathFormat
变量,是文件路径格式的groupId,可以用。
为了配置报名,类的package自适应,我们需要重新设计包名,并需要在生成好的archetype原型内修改代码,有两部分需要修改:
* 关于包名:为了让maven明白包名是占位符,我们需要使用特殊的命名方式,两个下划线__
,作为包名开头和结尾。也就是说,如果包名设计是org.liqiang.mvntest
,其中org.liqiang
是groupId,mvntest
是artifactId,那么我们设计工程原型的包名就是__packageInPathFormat__.__artifactId__
* 关于类内的package等和包名关联的信息:类内的信息,在maven生成的时候,都可以通过占位符自动替换,引用maven变量的格式是${package}
,${groupId}
,${artifactId}
等。但是因为转义的原因,生成archetype的时候并不能设置这些,需要等生成了archetype之后,去源文件内修改。需要去每一个类文件里将对应的包名替换掉。
未解决的问题
我试了好多次,包名命名成groupId.artifactId的操作(就是archetype工程写成__packageInPathFormat__.__artifactId__
),但是我失败了,基于原型出来的工程,只有groupId没有artifactId,百思不解。附一些网址,说不定对这个问题有帮助:
Package names in project generated from Maven archetype
How is metadata about an archetype stored?