maven 项目骨架生成工具
mvn archetype:generate
基本约定
- 源码 src/main/java
- 资源 src/main/resources
- 测试源码 src/test/java
- 测试资源 src/test/resources
- 编译输出 target/classes
- 打包 jar
- 打吧输出 target/
- webapp资源 webapp/.html webapp/.jsp webapp/img/ webapp/css/ webapp/js/
- webapp配置 webapp/WEB-INF/web.xml
mvn 构件坐标
通过坐标确定唯一的构件
- groupId 实际项目, 如SpringFramework
- artificatId 实际项目下的maven项目(模块),一般以实际项目作前缀,如spring-core
- version
- packaging 默认为jar
- classifier
依赖管理
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
声明依赖的构件的基本坐标
- groupId
- artificateId
- version
其他属性 - scope 作用在classpath的范围
- optional 构件A 的optional 依赖,不传递给依赖构件A的其他构件
- exclusion 构件A 依赖了构件B,但是排除构件B的某些依赖
传递律
依赖遵循传递律。若存在对同一构件不同版本的依赖则
- 依赖路径最短的优先
- 最先被读取的依赖优先。
scope
决定依赖是否被添加到对应的编译/测试/运行时的classpath 中。
scope | 编译 | 测试 | 运行 |
---|---|---|---|
compile | y | y | y |
test | y | ||
provided | y | y | |
runtime | y | y | |
system | y | y |
provided 适用于运行时的库会存在在环境中,比如servlet-api
runtime 适用于编译时只需要interface, 实际运行时才会引入具体实现
system 适用于引用本机系统相关的依赖,依赖不由maven 管理,需要在systemPath 中声明
变量
- 内置变量
${basedir}
${version}
- POM属性
${project.groupId}
(通过 . 来访问pom元素) - 自定义属性:<properties> 中的属性, ${ 属性名 }
- Settings属性:settings 里的属性,通过
${ settings.??? }
访问 - Java 属性:所有Java 属性都可以直接访问, 如
${ user.home }
- 环境变量: 通过
${ env.??? }
访问
生命周期
将生命周期的phase 作为参数传递给mvn 执行
mvn clean install
会顺序执行该phase前所有的phase,如mvn clean 会执行pre-clean, clean两个phase
列举三个生命周期中常见的phase
clean 清理
- pre-clean
- clean
- post-clean
default 构建
- validate
- process-sources 复制src/main/resources 到classpath
- compile 编译src/main/java 到classpath
- process-test-sources 复制测试资源 src/test/resources 到classpath
- test-compile 编译测试代码 ssrc/test/java 到classpath
- test 运行单元测试
- package
- integration-test
- verify
- install 安装到本地仓库
- deploy 发布到远程仓库
site 建立站点
- site 生成站点文件
- site-deploy 发布到服务器上
插件
获取插件信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-clean-plugin:3.0.0 -Ddetail
插件定义了可执行的goal,可以通过
mvn {插件前缀}:{goal}
// 如 mvn clean:clean
插件:goal 直接执行
或者将插件绑定在phase 上,在执行phase 的时候执行
<build>
<plugins>
<plugin>
<artifactId>maven-sources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
POM 聚合
将多个模块放到同一aggreator pom中,一次构建就可以构建所有模块
<groupId>com.lxian.playground</groupId>
<artifactId>playground-mvn-aggreator</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>playground-java</module>
<module>playground-scala</module>
</modules>
- packaging 必须为 pom
- model 的值是该模块相对 aggreator pom的相对路径,比如上面配置的aggreator 应在 playground/pom.xml, 而playground-java 模块在 playgournd/playground-java/pom.xml
POM 继承
常用的可以继承的元素
- groupId
- version
- 各种作者/组织等描述
- distributionManagement
- properties
- dependencies
- dependencyManagement 只约束依赖的属性(version, scope),子POM可以按需要引入依赖
- pluginManagement 同上
- repositories
- build
由于不会继承modules 所以所以父pom和aggreator pom 可以为同一个🌚
父pom packaging 需为pom
<groupId>com.lxian.playground</groupId>
<artifactId>playground-mvn-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
子pom 可以指定父pom 的相对路径,默认为 ../pom.xml。如果相对路径上没找到父pom,则会在本地仓库搜索。
<parent>
<groupId>com.lxian.playground</groupId>
<artifactId>playground-java</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
仓库配置
坐标与路径
groupId/artifactId/version/artifactId-version.packaging
本地/远程仓库
本地仓库位置
~/.m2/repository
查找顺序
- system 依赖,从本地查找
- 从本地仓库查找
- 从远程仓库查找
- 如果是RELEASE 依赖,则读取远程 groupId/artifactId/version/maven-metadata.xml 确定最新发布版
- 如果是LATEST, 同上,查找包括snapshot 的最新版
- SNAPSHOT 则查找最新的 SNAPSHOT
构件会被先下载到本地再使用
配置
<repositories>
<repository>
<id>central</id>
<name>Maven Central</name>
<url>http://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
- updatePolicy 从远程仓库更新的频率 never/always/daily/interval。always会每次都检查更新
认证
配置在settings.xml (密码和代码分离)
<servers>
<server>
<id>my-repo</id>
<username></username>
<password></password>
<server>
</servers>
id 需要和pom repositories 里面的id 对应
部署配置
<distributionManagement>
<repository>
<id>my-release-repo</id>
<name>My Release Repo</name>
<url></url>
</repository>
<snapshotRepository>
...
</snapshotRepository>
</distributionManagement>
Snapshot
Snapshot 的发布,会在版本后带上发布时的时间戳
Snapshot 的依赖会拉去最新的Snapshot 构件