《项目管理利器Maven》学习(九):Maven核心之依赖管理

       Maven依赖范围

       之前我们说过,maven坐标能够确定一个项目。换句话说,我们可以用它来解决依赖关系。在POM中,依赖关

是在dependencies部分中定义的。在上面的POM例子中,我们用dependencies定义了对于junit的依赖:

       pom.xml配置文件代码:

  <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
  </dependencies> 

       那这个例子很简单,但是实际开发中我们会有复杂得多的依赖关系,因为被依赖的jar文件会有自己的依赖关系。

那么我们是不是需要把那些间接依赖的 jar文件也都定义在POM中呢?答案是不需要,因为maven提供了传递依赖的

特性。

       所谓传递依赖是指maven会检查被依赖的jar文件,把它的依赖关系纳入最终解决的依赖关系链中。在POM的

dependencies部分中,scope决定了依赖关系的适用范围。Maven提供了三种classpath:编译、测试和运行。我们

的例子junit的scope是test,那么它只会在执行 compiler:testCompile and surefire:test目标的时候才会被加到

classpath中,在执行compiler:compile目标时是拿不到junit的。

       我们还可以指定scope为provided,意思是JDK或者容器会提供所需的jar文件。比如说在做web应用开发的时

候,我们在编译的时候需要servlet API jar文件,但是在打包的时候不需要把这 jar文件打在 WAR 中,因为servlet容

器或者应用服务器会提供的。

       scope的默认值是compile,即任何时候都会被包含在classpath中,在打包的时候也会被包括进去。

       <scope>元素表示这个依赖包的范围,有六个值:

       1.compile:默认的范围,在编译和打包时都会将依赖存储进去 ;

       2.provided:在编译和测试的过程有效,最后生成war包时不会加入,诸如:servlet-api,因为servlet-api,

tomcat等web服务器已经存在了,如果再打包会冲突  ;

       3.runtime:只在运行的时候依赖,在编译的时候不依赖 ;

       4.test:范围指的是测试范围有效,在编译和打包时都不会使用这个依赖 ;

       5.system:与本机系统相关联,可移植性差;

       6.import:导入的范围,它只使用在<dependencyManagement>中,表示从其它的pom中导入

<dependency>的配置。

       Maven传递依赖

       我们假设项目demo2依赖项目demo1,项目demo3依赖项目demo2,那么项目demo3对项目demo1的依赖就

是传递依赖。

      我们来实现这个例子:

      首先建立三个Maven项目:demo1、demo2和demo3 :

      

       因为demo2依赖demo1,因此先在demo2中加入demo1的依赖,也就是在demo2的POM中添加如下代码:

<dependency>
        <groupId>com.demo</groupId>
        <artifactId>demo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

       我们编译项目demo2,出现以下的错误:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building demo2 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for com.demo:demo1:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.389 s
[INFO] Finished at: 2016-12-29T19:23:42+08:00
[INFO] Final Memory: 7M/71M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project demo2: Could not resolve dependencies for project com.demo:demo2:jar:0.0.1-SNAPSHOT: Could not find artifact com.demo:demo1:jar:0.0.1-SNAPSHOT -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

       上面出现错误是我们找不到项目demo2依赖的demo1的jar包,因为在本地仓库和远程仓库中都没有,因此报

错,这就需要我们手动打包demo1成为jar包加入到本地仓库。我们先来打包demo1成jar包加入到本地仓库供

demo2使用。

      
   

       这回我们再次编译demo2就会成功:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building demo2 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo2 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\Java\JavaEE\Demo\demo2\src\main\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo2 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\Java\JavaEE\Demo\demo2\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.540 s
[INFO] Finished at: 2016-12-29T19:41:22+08:00
[INFO] Final Memory: 13M/129M
[INFO] ------------------------------------------------------------------------

       编译成功后还是打包demo2下喜爱那个木加入到本地仓库供demo3项目使用。

       因为demo3依赖demo2,因此先在demo3中加入demo2的依赖,也就是在demo3的POM中添加如下代码:

    <dependency>
        <groupId>com.demo</groupId>
        <artifactId>demo3</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

       这一次我们demo3成功编译。

       我们看看各个项目的依赖管理下的依赖项和依赖树:

       

       

       排除依赖传递

       假设demo3只是依赖demo2,不依赖demo1,这就用到了排除依赖传递,那么我们需要在demo3中的POM中

加入如下的代码:

    <dependency>
        <groupId>com.demo</groupId>
        <artifactId>demo2</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <exclusions>
             <exclusion>
                  <groupId>com.demo</groupId>
                  <artifactId>demo1</artifactId>
             </exclusion>
        </exclusions>
    </dependency>

       那么我们再看demo3项目的依赖管理不会看到demo1

       

       Maven依赖冲突

       Maven依赖冲突的有两个原则:

       1.短路优先

       A->B->C->X(jar)

       A->D->X(jar)

       那么项目A会使用D的jar包的版本。

       假设我们的项目demo1依赖的如下的jar版本的包:

   <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
       demo2依赖如下的jar版本的包:

   <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.0</version>
    </dependency>
       demo3则使用demo2的依赖:

       

       2.先声明先优先

       如果路径长度相同,则谁先声明,先解析谁。

       假如我们的项目demo3同时依赖demo1和demo2,在上面的例子中我们先将demo2依赖demo1的依赖删除。

在demo3中同时加入demo1和demo2的依赖,如下面的代码:

    <dependency>
        <groupId>com.demo</groupId>
        <artifactId>demo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    
    <dependency>
        <groupId>com.demo</groupId>
        <artifactId>demo2</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

        我们看依赖的版本:

        

        关于Maven依赖管理就说这么多。

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值