maven的依赖范围

maven在编译、测试和运行的时候使用的是三套不同的classpath,pom中的依赖配置项的scope属性就是用来配置该依赖项在哪个范围内生效。Maven有下边几种依赖范围:

  1. compile:编译依赖范围。如果没有依赖包没有指定scope属性,那么默认情况下就是此依赖范围。这个依赖范围对于编译、测试和运行三种classpath都有效。比如说spring-beans这个依赖包。

  2. test:测试依赖范围。只对测试classpath有效。在编译主代码或者运行项目的时候是无法使用此包的。比如说junit。

  3. provided:已提供依赖范围。对于编译和测试的classpath有效,在运行无效。比如说servlet-api,在编译和测试的时候需要这个依赖包,但在项目运行的时候不需要。因为tomcat已经提供了这个包。

  4. runtime:运行时依赖范围。对于测试和运行的classpath有效,对于编译无效。比如jdbc驱动包。因为代码都是针对jdbc接口去写的,没有针对实现。所以在编译时即使没有驱动的实现包也是可以编译通过的。但如果要测试或者运行的时候,就要加载实现包了。

  5. system:系统依赖范围。该依赖与三种classpath的关系类似于provided。但必须与systemPath元素配合使用才可以,但这种情况虽然可以指定系统的jar包路径,但造成了与本机绑定的情况,无法移植

<dependency>
    <groupId>javax.sql</groupId>
    <artifactId>jdbc-my</artifactId>
    <version>1</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
依赖范围 编译classpath有效 测试classpath有效 运行classpath有效 例子
compile Y Y Y spring-beans
test - Y - junit
provided Y Y - servlet-api
runtime - Y Y jdbc驱动实现
system Y Y - 本地的,maven仓库之外的类库文件

maven的依赖调解

假如项目A的依赖关系是A->B-C-X(1.0),A->D-X(2.0)。这个时候有两个版本的X,那么选哪一个呢。maven依赖调解的第一个原则是路径短者优先。所以会引入X的2.0版本。

如果依赖路径的长度相同的话,该怎么处理呢?比如说A-B-Y(1.0),A-C-Y(2.0)。这个时候会应用第二个原则最先声明者优先。如果B的依赖声明在C之前,那么引入的Y的版本就是1.0.

maven的可选依赖(不常用)

比如说这样的依赖关系A->B,B->X(可选),B->Y(可选)。假如A对B的依赖范围是compile,B对X和Y的依赖范围也是compile,那么根据依赖的传递性,A也会引入X和Y。但是这里X和Y对B来说是可选依赖,A就不会引入X和Y。A如果要使用X和Y需要单独引入!

<optional>true</optional>

排除依赖

依赖的传递性可以很方便的引入项目需要的依赖,但也存在一些问题。假如A->B,B->C。但是这里的C是SNAPSHOT版本的,会影响项目的稳定性。所以在构建A项目的时候需要把这个快照版本排除掉,单独的在A的pom文件中申明对C的可靠版本的依赖。

<project>
    <groupId>com.clgate.cn</groupId>
    <artifactId>A</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>com.clgate.cn</groupId>
            <artifactId>B</artifactId>
            <version>1.0.0</version>
            <exclusions>
                <exclusion>
                    <groupId>com.clgate.cn</groupId>
                    <artifactId>C</artifactId>
                </exclusions>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.clgate.cn</groupId>
            <artifactId>C</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
</project>

归类依赖

主要的目的就是统一相同groupId,不同artifactId的版本

<project>
    xxxxx
    xxxxx
    xxxxx
    <properties>
        <spring.version></spring.version>
    </properties>
    
    <dependencies> 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>   
</project>

852774731
975 声望7 粉丝

引用和评论

0 条评论