3.5 依赖,聚合,继承
关系示意图 graphic
 一、依赖
我们项目中依赖的jar包可以通过依赖的方式(dependencies元素下添加dependency子元素)引入。       
graphic
 
 
1.依赖范围
通过控制依赖的范围,可以指定该依赖在什么阶段有效。         
graphic
 
maven的几种依赖范围(<scope></scope>)
 
graphic
 
 
2.依赖具有传递性
 
 
2.1依赖传递的规则
 规则-级别一样,就先用第一个,级别不一样,就用级别最少的
解释:级别(依赖的层次)一样的,就按照顺序,依赖第一个(层次为0);如果出现层次(层次>0),就先依赖层次最少的;
2.2去除依赖的两种方式
选择性依赖
在依赖中用<optional>直接去除这种依赖传递的特性,也就是说,如果别的项目引用设置了此依赖的项目,这个commons-longging不会被依赖到。例如在项目A中配置commons-logging的依赖,如果项目B依赖项目A,那么,此时项目B中不会依赖commons-logging了。
[html] view plain copy
print?
 
    <!-- 排除依赖 -->   
      
     <dependency>  
      
     <groupId>commons-logging</groupId>  
      
     <artifactId>commons-logging</artifactId>  
      
     <version>1.1.1</version>  
      
     <optional>true<optional>  
      
     </dependency>  
 
 
排除依赖
如果第三方的jar包没有用<optional>去除依赖的传递性,那么我们可以在当前的项目中使用<exclusion>元素声明排除依赖。例如,项目A中配置了spring-core的依赖,如果项目B需要引用项目A,但是同时又不需要commons-logging的包,这个时候使用<exclusion>元素排除即可,这种用法可以刻解决包版本冲突的问题。
 
     <dependency>     
             <groupId>org.springframework</groupId>     
             <artifactId>spring-core</artifactId>   
                <exclusions>  
                        <exclusion>  
                                <groupId>commons-logging</groupId>  
                                <artifactId>commons-logging</artifactId>  
                        </exclusion>   
                </exclusions>     
    </dependency>  
 
 
 二、聚合
 一个项目往往由多个模块构成的,在进行构建时,针对每个模块都进行构建命令是一件非常繁琐又容易出错的事情,所以Maven的聚合功能能够替我们完成进行一次构建命令完成全部模块的构建。
 
 Maven的聚合功能可以通过一个父模块将所有的要构建模块整合起来,将父模块的打包类型声明为POM,通过<modules>将各模块集中到父POM中。 
 
    <modules>  
            <module>user-core</module>  
            <module>user-log</module>  
      
            <module>user-service</module>  
      
    </modules>  
          原理:父类型的模块,不需要有源代码和资源文件,也就是说,没有 src/main/Java 和 src/test/java 目录。Maven会首先解析聚合模块的 POM 文件,分析要构建的模块,并通过各模块的依赖关系计算出模块的执行顺序,根据这个潜在的关系依次构建模块。
 
 
三、继承
         Maven中继承的概念与面向对象的继承概念是一致的,通过继承消除重复编码的行为。在这里,我们也可以用一个父模块来完成父模块与子模块共用依赖的继承关系。父模块的POM文件声明与平常一样,提取公共地方,子模块需要继承父模块。
 
 
3.5.1 依赖
项目中引入的jar包(dependencies元素下添加dependency子元素)我们称作依赖。
依赖范围
Maven的依赖范围就是用来控制与编译、测试、运行三种classpath的关系。
Maven有以下几种依赖范围:
1.compile 的范围
当依赖的scope为compile的时候,那么当前这个依赖的包,会在编译的时候将这个依赖加入进来,并且在打包(mvn package)的时候也会将这个依赖加入进去
意思就是:编译范围有效,在编译与打包时都会存储进去
2.provided的范围
当依赖的scope为provided的时候,在编译和测试的时候有效,在执行(mvn package)进行打包成war包的时候不会加入,比如:servlet-api,因为servlet-api,tomcat等web服务器中已经存在,如果在打包进去,那么包之间就会冲突
3.test的范围
当依赖的scope为test的时候,指的的是在测试范围有效,在编译与打包的时候都不会使用这个依赖
4.runtime的范围
当依赖的scope为runtime的时候,在运行的时候才会依赖,在编译的时候不会依赖
5.system (系统范围)
system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)。
注:在默认的情况下scope的范围是compile
传递性
规则
1、路径最近者优先,c->b->a  c依赖b,b依赖a,c会优先用b的jar包。
 
2、路径相同配置最前者优先,c->b,c->a,c依赖b,c也依赖a,必须要看b、a在c中哪个先声明,优先使用先声明的jar包。
去除依赖
选择性依赖<optional/>
选择性依赖
在依赖中用<optional>直接去除这种依赖传递的特性,也就是说,如果别的项目引用设置了此依赖的项目,这个commons-logging不会被依赖到。例如在项目A中配置commons-logging的依赖,如果项目B依赖项目A,那么,此时项目B中不会依赖commons-logging了。
    <!-- 排除依赖 -->  
<dependency>       <groupId>commons-logging</groupId>             <artifactId>commons-logging</artifactId>   
<version>1.1.1</version>   
<optional>true</optional>     
 </dependency>  
排除依赖<exclusion/>
排除依赖
如果第三方的jar包没有用<optional>去除依赖的传递性,那么我们可以在当前的项目中使用<exclusion>元素声明排除依赖。例如,项目A中配置了spring-core的依赖,如果项目B需要引用项目A,但是同时又不需要commons-logging的包,这个时候使用<exclusion>元素排除即可,这种用法可以刻解决包版本冲突的问题。
     <dependency>     
             <groupId>org.springframework</groupId>     
             <artifactId>spring-core</artifactId>   
                <exclusions>  
                        <exclusion>  
                                <groupId>commons-logging</groupId>  
                                <artifactId>commons-logging</artifactId>  
                        </exclusion>   
                </exclusions>     
    </dependency> 
3.5.2 聚合
一个项目往往由多个模块构成的,在进行构建时,针对每个模块都进行构建命令是一件非常繁琐又容易出错的事情,所以Maven的聚合功能能够替我们完成进行一次构建命令完成全部模块的构建。
 
 Maven的聚合功能可以通过一个父模块将所有的要构建模块整合起来,将父模块的打包类型声明为POM,通过<modules>将各模块集中到父POM中。 
    <modules>  
            <module>user-core</module>  
            <module>user-log</module>  
            <module>user-service</module>  
    </modules>  
通过一个父模块把所有子模块整合到一起
See related topics and documents
父模块的打包类型设置为POM
3.5.3 继承
Maven中继承的概念与面向对象的继承概念是一致的,通过继承消除重复编码的行为。在这里,我们也可以用一个父模块来完成父模块与子模块共用依赖的继承关系。父模块的POM文件声明与平常一样,提取公共地方,子模块需要继承父模块。
 做法:子模块加入parent标签进行继承
 
注意:
1、子模块没有声明groupId和version, 这两个属性继承至父模块。但如果子模块有不同与父模块的 groupId、version ,也可指定;
2、不应该继承artifactId,如果groupId ,version,artifactId 完全继承的话会造成坐标冲突;另外即使使用不同的 groupId或version,同样的 artifactId也容易产生混淆。
3、使用继承后 parent也必须像子模块一样加入到聚合模块中。
 
 
Maven可继承的POM 元素
groupId :项目组 ID ,项目坐标的核心元素;
version :项目版本,项目坐标的核心元素;
description :项目的描述信息;
organization :项目的组织信息;
inceptionYear :项目的创始年份;
url :项目的 url 地址
develoers :项目的开发者信息;
contributors :项目的贡献者信息;
distributionManagerment :项目的部署信息;
issueManagement :缺陷跟踪系统信息;
ciManagement :项目的持续继承信息;
scm :项目的版本控制信息;
mailingListserv :项目的邮件列表信息;
properties :自定义的 Maven 属性;
dependencies :项目的依赖配置;
dependencyManagement :醒目的依赖管理配置;
repositories :项目的仓库配置;
build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;
reporting :包括项目的报告输出目录配置、报告插件配置等。
子模块继承父模块