看到一份2018 年 JVM 生态报告提到,使用构建工具的比例,maven高达60%,远高于gradle的19%。html
我日常也使用maven,因而就整理了一些maven的经常使用知识。
关于maven的博文已经浩如烟海 ,因此这里我只是总结一些本身经常使用知识,以作备忘。web
分为本地仓库和远程仓库
远程仓库默认使用的是 Maven 社区提供的中央仓库apache
还有其余社区提供的仓库,如jcenter,jboss。
通常公司都会使用Nexus部署一个私服(也是仓库),用于存放公司内部构件。
mvn deploy 能够将项目生成的构件分发到私服。缓存
由于中央仓库通常部署在外国,下载构件速度比较慢,因此能够经过镜像mirror下载, mirrorOf配置代理仓库。
当须要从代理仓库下载构件时,都会转为从镜像下载。
镜像中不存在该构件时,镜像会从仓库下载,缓存到镜像中。
须要注意的是,因为镜像彻底屏蔽了代理仓库,当镜像不稳定或者中止服务的时候,Maven不会直接访问代理仓库,于是将没法下载构件。
最经常使用的是阿里提供的镜像服务:tomcat
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
profile用于定义不一样环境的不一样配置,如开发,测试环境使用不一样的仓库,打包方式等。
mvn clean package -Ppro即构建出pro环境须要的war包app
构造Java项目mvn archetype:generate -DinteractiveMode=false -DgroupId=com.binecy -DartifactId=my-core
webapp
构造Web项目mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.binecy -DartifactId=my-web
maven
构造子模块
构造父模块# mvn archetype:generate -DinteractiveMode=false -DgroupId=com.binecy -DartifactId=system-core
进入system-core项目# cd system-core
删除不须要的src文件夹# rm src
工具
修改pom.xml文件,将<packaging>jar</packaging>修改成<packaging>pom</packaging>
构造子模块system-dao# mvn archetype:generate -DinteractiveMode=false -DgroupId=com.binecy -DartifactId=system-dao
构造子模块system-web# mvn archetype:generate -DinteractiveMode=false -DgroupId=com.binecy -DartifactId=system-web
测试
这时父模块的pom.xml已经自动添加了module信息
<?xml version="1.0" encoding="UTF-8"?> <project 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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.binecy</groupId> <artifactId>system-core</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <name>system-core</name> <url>http://maven.apache.org</url> <modules> <module>system-service</module> <module>system-web</module> </modules> </project>
一个多模块的项目构造完成。
dependencyManagement
父模块中定义的dependencies,子模块默认继承,不需重复定义也可使用。
父模块中定义的dependencyManagement只是声明依赖,并不实现引入,若是子模块也定义了该依赖,能够继承父模块dependencyManagement中定义的version和scope,不用须要声明这两个属性。
若是子模块也声明了version属性,则使用子模块声明的版本。
跳过测试mvn install -Dmaven.test.skip=true
使用tomcat插件
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <path>/</path> <port>9090</port> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin>
依赖传递
若是咱们的项目A依赖构件B,而构件B又依赖于构件C,依赖的关系为:A—>B—>C
当咱们执行项目A,maven会下载构件B,构件C
依赖冲突
若是有一下依赖关系
A—>B—>C(version:0.0.1)
A—>D>—C(version:0.0.2)
那么项目A引入哪一个版本的构件C呢?
这里有两个重要的依赖调解原则。
1:若是依赖路径的长度不一样,则“短路优先”:
A—>B—>C—>D—>E—>X(version 0.0.1) A—>F—>X(version 0.0.2) 则A依赖于X(version 0.0.2)。
2:依赖路径长度相同状况下,则“先声明优先”:
A—>E—>X(version 0.0.1) A—>F—>X(version 0.0.2) 若是项目A的depencies先声明引入E,这A依赖于X(version 0.0.1)
依赖冲突,一般是低版本的依赖覆盖了高版本的依赖,而某些构件使用了高版本特有的功能致使的。这时可使用dependency:tree分析依赖关系,使用exclusions排除重复的依赖或者添加优化级更高的正确依赖。
参考:
Maven 核心原理