maven烂笔头
程序员文章站
2022-07-12 18:42:21
...
1. pom的继承依赖
如果父pom中使用的是<dependencies>....</dependencies>方式,则子pom会自动使用pom中的jar包,如果父pom使用<dependencyManagement><dependencies>....</dependencies></dependencyManagement>方式,则子pom不会自动使用父pom中的jar包,这时如果子pom想使用的话,就要给出groupId和artifactId,无需给出version
2. 依赖管理
maven的生命周期,http://www.cnblogs.com/tenghoo/p/maven_life_cycle.html
Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。各个生命周期相互独立(比如执行mvn package,则不会执行clean的操作),一个生命周期的阶段前后依赖(比如执行mvn package,则会自动也执行package之前的validate,compile,test阶段)。
2.1 Transitive Dependency (传递依赖)
你的项目依赖于A,A又依赖于B。你的项目是否要声明你依赖于B? Maven的回答是它帮你自动管理这种依赖的传递,你不需要声明你依赖于B,由Maven来做(这就是传递依赖)。
但如A -> B -> C -> D 2.0,同时存在A -> E -> D 1.0,那么应该使用D1.0还是D2.0呢?用Maven的话来说,这件事情叫做“Dependency Mediation”(依赖仲裁),当出现这种冲突时,采用“Nearest Definition”的解决办法,即采用最短路径,在上述例子中仲裁的结果是D1.0,因为它的路径更短。如果两个路径长短是一样的呢?那么只能是谁先出现就选谁了。上述例子中如果你显式声明A依赖于D2.0,那么Maven就会帮你选取D2.0而不是D1.0。这有时候会带来一些版本不一致的问题和疑惑。
避免传递依赖引起版本问题的最佳实践:现在很多的开源框架和工具都开始分模块打包发布,比如spring,hibernate都是如此,而这些模块之间又 有可能存在相关的依赖关系,为了避免出现版本不一致问题,比如上例中出现的spring-jms使用的是3.0.2,而spring-core却使用了 3.0.3这种情况,需要我们对一个工程直接依赖的某一框架的多个模块都要做出声明,而不要依赖其内部的依赖关系来间接引入。总结起来就是:一般来说,如 果工程直接依赖到某一框架的多个模块,最好全部声明这些依赖。
http://www.cnblogs.com/alfredxiao/archive/2010/09/15/maven_dependency_mgmt.html
http://blog.csdn.net/bluishglc/article/details/6584678
2.2 Dependency Scope (依赖范围)
举例来说,你开发时需要做测试,你需要依赖于junit的jar,但是部署应用时并不需要它,因为单元测试不会在生产环境上跑,也就是说最终打包的jar 或者war不包含junit的jar。又如你开发web程序,你的servlet/jsp进行编译需要依赖于servlet-jsp的标准 api(J2EE的jar),但是部署时也是不需要它的,因为你的应用服务器肯定有这些东西。
因此,Maven考虑了6种可能的scope供选择:
- compile: 默认的scope。编译、测试、打包全都需要。compile参与依赖传递,就是说,你的项目A依赖于B(依赖scope是compile),项目C依赖于你的项目A,那么C也就依赖于B。
- provided: 表示JDK或者容器会在Runtime时提供这些(jar),如上面说到的servlet api。provided的东西在编译和测试时会用到,不参与传递依赖。
- runtime: 表示编译时不需要,但测试和运行时需要,最终打包时会包含进去。
- test: 只用于测试阶段(测试的编译和测试的运行),典型的就是junit的jar。
- system: 和provided类似,但要求jar是你的系统里已有的,不会在repository里找,如rt.jar,tools.jar这些。
- import: 简单的说,你的项目的pom可以继承另一个项目的pom,从而继承了父项目的依赖关系,但是因为之后single inheritance的限制,所以创造了import,使得你可以“导入”或者说“继承”任何一到多个项目的依赖关系。
如果你的项目依赖于A(scope1),A依赖于B(scope2),那么你的项目对B的依赖应该算是哪个scope呢?官方文档上有 个表格,列举了scope1和scope2的一个矩阵关系。
2.3 依赖冲突解决
上面说道为了防止传递依赖带来的版本冲突,可以在工程中声明所有工程依赖的工程,但是如果没有这样做,又想避免某jar包的版本问题,可以如下排除指定jar包依赖传递:
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>asm</groupId>
</exclusion>
</exclusions>
2.4 ide依赖管理
在idea中可以在某个pom文件上右键
可以看到该pom文件的依赖关系,可以放大或选择不同的layout来展示这个关系。右键某个jar依赖可以进行exclude等操作。对pom文件的改动idea不会自动更新这个依赖图,需要在pom文件上右键maven->reimport重新加载。当然也可以通过maven的命令查看依赖树:mvn dependency:tree
3. 多module工程,多war包工程,可以选择只打某个war出来
maven的反应堆功能:
mvn package -pl module-name/ -am
注意-am是同时编译module-name依赖的模块, 而-amd是反向依赖。
4. deploy时跳过某个模块,就在该模块的pom中添加下面
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
如果父pom中使用的是<dependencies>....</dependencies>方式,则子pom会自动使用pom中的jar包,如果父pom使用<dependencyManagement><dependencies>....</dependencies></dependencyManagement>方式,则子pom不会自动使用父pom中的jar包,这时如果子pom想使用的话,就要给出groupId和artifactId,无需给出version
2. 依赖管理
maven的生命周期,http://www.cnblogs.com/tenghoo/p/maven_life_cycle.html
Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。各个生命周期相互独立(比如执行mvn package,则不会执行clean的操作),一个生命周期的阶段前后依赖(比如执行mvn package,则会自动也执行package之前的validate,compile,test阶段)。
2.1 Transitive Dependency (传递依赖)
你的项目依赖于A,A又依赖于B。你的项目是否要声明你依赖于B? Maven的回答是它帮你自动管理这种依赖的传递,你不需要声明你依赖于B,由Maven来做(这就是传递依赖)。
但如A -> B -> C -> D 2.0,同时存在A -> E -> D 1.0,那么应该使用D1.0还是D2.0呢?用Maven的话来说,这件事情叫做“Dependency Mediation”(依赖仲裁),当出现这种冲突时,采用“Nearest Definition”的解决办法,即采用最短路径,在上述例子中仲裁的结果是D1.0,因为它的路径更短。如果两个路径长短是一样的呢?那么只能是谁先出现就选谁了。上述例子中如果你显式声明A依赖于D2.0,那么Maven就会帮你选取D2.0而不是D1.0。这有时候会带来一些版本不一致的问题和疑惑。
避免传递依赖引起版本问题的最佳实践:现在很多的开源框架和工具都开始分模块打包发布,比如spring,hibernate都是如此,而这些模块之间又 有可能存在相关的依赖关系,为了避免出现版本不一致问题,比如上例中出现的spring-jms使用的是3.0.2,而spring-core却使用了 3.0.3这种情况,需要我们对一个工程直接依赖的某一框架的多个模块都要做出声明,而不要依赖其内部的依赖关系来间接引入。总结起来就是:一般来说,如 果工程直接依赖到某一框架的多个模块,最好全部声明这些依赖。
http://www.cnblogs.com/alfredxiao/archive/2010/09/15/maven_dependency_mgmt.html
http://blog.csdn.net/bluishglc/article/details/6584678
2.2 Dependency Scope (依赖范围)
举例来说,你开发时需要做测试,你需要依赖于junit的jar,但是部署应用时并不需要它,因为单元测试不会在生产环境上跑,也就是说最终打包的jar 或者war不包含junit的jar。又如你开发web程序,你的servlet/jsp进行编译需要依赖于servlet-jsp的标准 api(J2EE的jar),但是部署时也是不需要它的,因为你的应用服务器肯定有这些东西。
因此,Maven考虑了6种可能的scope供选择:
- compile: 默认的scope。编译、测试、打包全都需要。compile参与依赖传递,就是说,你的项目A依赖于B(依赖scope是compile),项目C依赖于你的项目A,那么C也就依赖于B。
- provided: 表示JDK或者容器会在Runtime时提供这些(jar),如上面说到的servlet api。provided的东西在编译和测试时会用到,不参与传递依赖。
- runtime: 表示编译时不需要,但测试和运行时需要,最终打包时会包含进去。
- test: 只用于测试阶段(测试的编译和测试的运行),典型的就是junit的jar。
- system: 和provided类似,但要求jar是你的系统里已有的,不会在repository里找,如rt.jar,tools.jar这些。
- import: 简单的说,你的项目的pom可以继承另一个项目的pom,从而继承了父项目的依赖关系,但是因为之后single inheritance的限制,所以创造了import,使得你可以“导入”或者说“继承”任何一到多个项目的依赖关系。
如果你的项目依赖于A(scope1),A依赖于B(scope2),那么你的项目对B的依赖应该算是哪个scope呢?官方文档上有 个表格,列举了scope1和scope2的一个矩阵关系。
2.3 依赖冲突解决
上面说道为了防止传递依赖带来的版本冲突,可以在工程中声明所有工程依赖的工程,但是如果没有这样做,又想避免某jar包的版本问题,可以如下排除指定jar包依赖传递:
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>asm</groupId>
</exclusion>
</exclusions>
2.4 ide依赖管理
在idea中可以在某个pom文件上右键
可以看到该pom文件的依赖关系,可以放大或选择不同的layout来展示这个关系。右键某个jar依赖可以进行exclude等操作。对pom文件的改动idea不会自动更新这个依赖图,需要在pom文件上右键maven->reimport重新加载。当然也可以通过maven的命令查看依赖树:mvn dependency:tree
3. 多module工程,多war包工程,可以选择只打某个war出来
maven的反应堆功能:
mvn package -pl module-name/ -am
注意-am是同时编译module-name依赖的模块, 而-amd是反向依赖。
4. deploy时跳过某个模块,就在该模块的pom中添加下面
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
下一篇: <进阶-3> 对象的组合
推荐阅读
-
在Centos上搭建Maven*仓库的方法
-
使用maven+eclipse搭建struts2开发环境
-
解决Maven 项目报错 java.httpservlet和synchronized使用方法
-
maven安装以及eclipse配置maven的方法
-
解决maven执行命令时提示:cached in the local repository的解决方法小结
-
Eclipse创建Maven工程总是出现pom.xml报错怎么办?
-
Nexus-在项目中使用Maven私服,Deploy到私服、上传第三方jar包、在项目中使用私服jar包
-
盘点史上最烂的33个PS失误错误范例
-
Docker使用 Maven 插件构建镜像的方法
-
初次使用IDEA创建maven项目的教程