谈谈 Maven 的 settings.xml
问题起因
来公司开始使用 maven 以后, 会配置一个叫 settings.xml 的 maven 配置文件. 这个文件的内容不多, 格式大概如下:
<?xml version="1.0"?>
<settings 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/settings-1.0.0.xsd">
<servers>
<server>
<id>snapshots</id>
<username>{username}</username>
<password>{passwd}</password>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
</server>
</servers>
<profiles>
<profile>
<id>MyProfile</id>
<repositories>
<repository>
<id>Nexus</id>
<url>http://test.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<!-- always , daily (default), interval:X (where X is an integer in minutes) or never.-->
<updatePolicy>daily</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>Nexus</id>
<url>http://test.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>MyProfile</activeProfile>
</activeProfiles>
</settings>
之前一直不太明白这个文件各部分都是什么意思, 查了文档 settings 配置指南 和 pom 配置指南 才大概明白此处的各个节点的意思.
<server /> 节点
<server /> 中定义了一些敏感的账号密码信息, 这些信息用于在发布新 jar 包的时候使用. 一般来讲, 我们只会填写 snapshot 的 username & password. 因为本地一般只会发布 snapshot 用于测试, 而 release 版本发布都是走 bds 发布系统, 所以不会写在这里.
根据文档的解释, 这里的 <id> 应该是需要对应 repository 或 mirror 的 id 值的, 但是这里的配置没有叫 snapshots 的 repository. 那么这个对应的 id 到底是什么呢? 原因在于 settings.xml 与 pom.xml 是联用的. 而我们一般在自己项目的 pom 里会引用公司的 super pom. 去 super pom 中查看, 可以看到一个信息如下
<distributionManagement>
<repository>
<id>releases</id>
<name>Nexus Releases</name>
<url>${nexus.releases}</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<uniqueVersion>false</uniqueVersion>
<name>Nexus Snapshots</name>
<url>${nexus.snapshots}</url>
</snapshotRepository>
</distributionManagement>
原来这个叫 snapshots 的 repository 定义在这里. 那么, distributionManagement 又是什么? 根据文档的解释, 这个是用来配置发布 jar 包的时候用的地址. 例如我们的 snapshot, 就会发布到 ${nexus.snapshots} 这个变量定义的地方. 而发布的时候验证的权限则是使用 servers 节点中定义的 username 与 password.
<profiles /> 节点
<profiles /> 节点中主要定义了我们 local repository 在获取依赖的时候访问的 url 地址. 我们可以发现它与 super-pom 的 profiles 定义类似.
<profiles>
<profile>
<id>local</id>
<properties>
<deploy.type>local</deploy.type>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<deploy.type>dev</deploy.type>
</properties>
</profile>
<profile>
<id>beta</id>
<properties>
<deploy.type>beta</deploy.type>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<deploy.type>prod</deploy.type>
</properties>
</profile>
</profiles>
他们的联系在于 settings.xml 中定义的 profile 值会覆盖 pom.xml 中相同的 id 的 profile 参数. 当然, 我们此处 pom 中并没有定义与 settings 中相同的 key. 所以此处可以理解为最后在使用 local profile 编译的时候, 会合并使用 settings 和 pom 中对 local profile 定义的参数.
小结
从配置上看, 我们的发布和编译实际上是使用不同的 url 的, 总共会涉及到获取依赖的 repository, 发布 jar 包的 repository 两部分 repository, 分别定义在 <profile> 和 <distributionManagement> 两个节点中.
另外, settings 文件分为两种:
- The Maven install: $M2_HOME/conf/settings.xml
- A user’s install: ${user.home}/.m2/settings.xml
当两个同时存在时, 会合并使用两个配置文件, 出现冲突时, 优先考虑用户目录下的 settings.xml
最后, 我之前在考虑为什么不把获取依赖的 repository 直接定义到 super-pom, 而是要每个人都去修改自己的 settings 文件, 定义到 settings 文件里呢? 我发现这其实是一个悖论, 因为 super-pom 也是通过我们定义的 repository 来获取的.