目录
一、依赖机制
1、基本的依赖配置格式:
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.8.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
其中version标签如果不配置,则Maven自动寻找最新的版本。
2、在Maven仓库中定位下载的依赖jar:
将groupId+artifactId+version按照格式连接起来:
com/starfall/maven/Maven/0.0.1-SNAPSHOT/Maven-0.0.1-SNAPSHOT.jar
3、全量的dependencies标签参考:
<dependencies>
<dependency>
<!--依赖的group ID -->
<groupId>org.apache.maven</groupId>
<!--依赖的artifact ID -->
<artifactId>maven-artifact</artifactId>
<!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。 -->
<version>3.8.1</version>
<!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,
尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。 -->
<type>jar</type>
<!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成
JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。 -->
<classifier></classifier>
<!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。 - compile :默认范围,用于编译 - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
- runtime: 在执行时需要使用 - test: 用于test任务时使用 - system: 需要外在提供相应的元素。通过systemPath来取得
- systemPath: 仅用于范围为system。提供相应的路径 - optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用 -->
<scope>test</scope>
<!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。 -->
<systemPath></systemPath>
<!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题 -->
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
<!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。 -->
<optional>true</optional>
</dependency>
</dependencies>
二、依赖范围
项目的主程序和测试程序不同阶段的有效性:
注意点:
- 编译依赖范围(compile)。该范围就是默认依赖范围,此依赖范围对 于编译、测试、运行三种都有效。
- 测试依赖范围(test)。最典型的例子就是 Junit, 构件在测试时才需要,所以它的依赖范围是测试,因此它的依赖范围需要显示指定为<scope>test</scope> ,当然不显示指定依赖范围也不会报错,但是该依赖会被加入到编译和运行的classpath中,造成不必要的浪费 。
- 已提供依赖范围(provided)。官方举了一个例子。比如在JavaEE web项目中我们需要使用servlet的API,但是呢Tomcat中已经提供这个jar,我们在编译和测试的时候需要使用这个api,但是部署到tomcat的时候,如果还加入servlet构建就会产生冲突,这个时候就可以使用provided。
- 运行时依赖范围(runtime)。典型例子就是JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动。
三、可传递性依赖
1、依赖的传递性
B依赖于其他库C。如果,另外一个项目 A想要使用 B ,那么A 项目也需要使用库C。
但是 A依赖B、B依赖C、那么A能不能使用C,需要查看B依赖C的范围是不是compile:
此时,Maven 提供一些功能来控制可传递的依赖的程度。
功能 | 功能描述 |
---|---|
依赖调节 | 决定当多个手动创建的版本同时出现时,哪个依赖版本将会被使用。 如果两个依赖版本在依赖树里的深度是一样的时候,第一个被声明的依赖将会被使用。 |
依赖管理 | 直接的指定手动创建的某个版本被使用。例如当一个工程 C 在自己的依赖管理模块包含工程 B,即 B 依赖于 A, 那么 A 即可指定在 B 被引用时所使用的版本。 |
依赖范围 | 包含在构建过程每个阶段的依赖。 |
依赖排除 | 任何可传递的依赖都可以通过 "exclusion" 元素被排除在外。举例说明,A 依赖 B, B 依赖 C,因此 A 可以标记 C 为 "被排除的"。 |
依赖可选 | 任何可传递的依赖可以被标记为可选的,通过使用 "optional" 元素。例如:A 依赖 B, B 依赖 C。因此,B 可以标记 C 为可选的, 这样 A 就可以不再使用 C。 |
2、依赖排除
例如在引入依赖Spring-core的jar时候,会同步的引入commons-logging的jar,说明Spring的jar依赖于commons-logging。
但是如果此时想要从依赖中排除掉commons-logging的jar时候,需要如下做法:
排除配置:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
3、依赖的原则
(3.1)路径最短
A项目依赖B、B项目依赖C。此时B、C中都有不同版本的log4j的依赖,在A项目中根据路径最短原则Maven会引用B声明的log4j版本。
(3.2)路径相同时,先声明者优先。
A项目依赖B和C,B、C中有两个版本的log4j依赖,则A中使用先声明的那个项目的依赖。
四、引入外部依赖
1、systemPath
如果存在自己打包的jar,不会存在Maven本地仓库、中央仓库及其远程仓库。只能在 src 文件夹下添加 lib 文件夹,然后将jar复制到该目录下。例如:
那么 Maven 构建将会失败,因为它在编译阶段使用指这个库无法下载或无法找到。
此时需要添加外部依赖项:
<dependencies>
<dependency>
<groupId>ldapjdk</groupId>
<artifactId>ldapjdk</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath> <!--项目根目录下的lib文件夹下-->
</dependency>
</dependencies>
- 指定 groupId 同样作为库的名称;
- 指定 artifactId 同样作为库的名称;
- 指定范围的系统;
- 指定相系统项目的位置;
2、定制库到Maven本地资源库
1中是把jar复制在项目中,另一种方法是将jar安装到Maven本地仓库中,这样可以使用正常的依赖引入此jar
示例:kaptcha,它是一个流行的第三方Java库,它被用来生成 “验证码” 的图片,以阻止垃圾邮件,但它不在 Maven 的中央仓库中。
安装 “kaptcha” jar 到Maven 的本地资源库,参考:https://www.yiibai.com/maven/include-library-manully-into-maven-local-repository.html
2.1、先准备好jar包,命名版本,并放在一个目录下:c:\kaptcha-2.3.jar
执行命令:
mvn install:install-file -Dfile=c:\kaptcha-{version}.jar -DgroupId=com.google.code -DartifactId=kaptcha -Dversion={version} -Dpackaging=jar
执行结果:
D:\>mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code
-DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing c:\kaptcha-2.3.jar to
D:\maven_repo\com\google\code\kaptcha\2.3\kaptcha-2.3.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Tue May 12 13:41:42 SGT 2014
[INFO] Final Memory: 3M/6M
[INFO] ------------------------------------------------------------------------
出现上述画面kaptcha-2.3.jar被复制到Maven本地仓库。
2.2、在pom中引用该jar:
<dependency>
<groupId>com.google.code</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3</version>
</dependency>
五、统一管理依赖的版本
1、使用<properties>标签统一依赖版本:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.starfall.ssm</groupId>
<artifactId>SSM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- 定义Spring、MyBatis版本 -->
<properties>
<spring.version>4.3.18.RELEASE</spring.version>
<aop.version>1.8.0</aop.version>
<mybatis.version>3.4.6</mybatis.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- AOP相关包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aop.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aop.version}</version>
</dependency>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
</project>
2、设置项目编码