pom.xml

作者: 不知名的蛋挞 | 来源:发表于2018-11-19 09:24 被阅读7次

    什么是pom?

    pom.xml文件是Maven进行工作的主要配置文件。在这个文件中我们可以配置Maven项目的groupId、artifactId和version等Maven项目必须的元素;可以配置Maven项目需要使用的远程仓库;可以定义Maven项目打包的形式;可以定义Maven项目的资源依赖关系等等。

    pom.xml标签解析

     <!--project是pom.xml的根元素,包含了一些约束的信息,比如xlms,xsi-->
    <project>
            <!--指定了当前pom的版本-->
             <modelVersion>4.0.0</modelVersion>
            <!--maven2.0必须是这样写,现在是maven2唯一支持的版本-->
            <!-- 基础设置 -->
            <groupId>反写公司的网址+项目名称</groupId>
            <artifactId>项目名称+模块名</artifactId>
            <version>当前项目版本号</version>
             <!-- 默认是jar,还可以打包成war/zip/pom-->
            <packaging>...</packaging>
            <!-- 项目描述名,一般是写项目文档的时候才使用 -->
            <name>...</name>
            <!-- 项目的地址-->
            <url>...</url>
            <!-- 项目的描述 -->
            <description>...</description>
            <!-- 开发人员的列表 -->
            <developers>...</developers>
            <!-- 许可证的信息 -->
            <licenses>...</licenses>
            <!-- 组织信息 -->
            <organization>...</organization>
    
            <!-- 依赖列表,下面可以包含多个依赖项dependency-->
            <dependencies>
               <dependency>
                   <!-- 指定坐标确定依赖项的位置 -->
                   <groupId></groupId>
                   <artifactId></artifactId>
                   <version></version>
                   <type></type>
                   <!-- 依赖包的依赖范围-->
                   <scope></scope>
                   <!-- 这个标签只有true和false两个值,是用来设置依赖是否可选 -->
                   <optional></optional>
                   <!-- 排除依赖传递列表 -->
                   <exclusions> 
                     <exclusion>
                     </exclusion>  
                   </exclusions>
                </dependency>
             </dependencies>
    
             <!-- 依赖管理,里面包含多个依赖,但是它并不会被运行,即不会被引用到实际的依赖中-->
             <!--这个标签主要是用来定义在父模块中,供子模块继承用 -->
             <dependencyManagement>                              
                 <dependencies>
                    <dependency>
                    </dependency>
                 </dependencies>
            </dependencyManagement>
    
             <!-- 常用于给构件的行为提供相应的支持 -->
              <build>
                <!-- 插件列表 -->
                <plugins>
                    <plugin>
                       <groupId></groupId>
                       <artifactId></artifactId>
                       <version></version>
                     </plugin>
                 </plugins>
              </build>
    
            <!-- 用于在子模块中对父模块的pom的继承 -->
            <parent>...</parent>
             <!-- 用来聚合多个模块,让多个模块进行编译,不用一个一个来 -->
            <modules>
              <module>
              </module>
            </modules>
    </project>
    

    1. groupId、artifactId和version

    在Maven中,使用groupId、artifactId和version组成groupdId:artifactId:version的形式来唯一确定一个项目。对于一个最简单的pom.xml的定义必须包含modelVersion、groupId、artifactId和version这四个元素,当然这其中的元素也是可以从它的父项目中继承的。

    • groupId : 指公司里面开发的某个项目,即组织名称,例如:zttc.itat.maven,在F盘目录下,将是: zttc/itat/maven目录。
    • artifactId : 项目里面某一个具体的模块,例如:maven-ch01,在F盘目录下,将是:zttc/itat/maven/maven-01目录。
    • version : 版本号,例如:版本号为1.0,在M2_REPO目录下,将是:org/codehaus/mojo/my-project/1.0目录。

    2. scope

    scope释就是依赖包的依赖范围。

    【scope的使用场景和说明】

    1.compile
      表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖,打包的时候也通常需要包含进去。

    2.provided
      相当于compile,但是在打包阶段做了exclude的动作,也就是当我们打包的时候就不会把这个依赖加进去。最常见的是j2ee规范相关的servlet-api和jsp-api等jar包,一般Tomcat会提供,无需在打包到war包中,如果不配置为provided,把这些包打包到工程war包中,在tomcat6以上版本会出现冲突无法正常运行程序(版本不符的情况)。

    3.runtime
      一般是运行和测试环境使用,编译时候不用加入classpath,打包时候会打包到目标包中。一般是通过动态加载或接口反射加载的情况比较多。与compile相比,跳过编译而已。

    4.test
      表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行,但是在项目编译和打包都不会使用这个依赖。比较典型的如junit。只有在src/test/java文件夹下面的才会用到这个作用域。

    5.system
      从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。

    【scope的依赖传递】

    比如我们引入某一个依赖spring-test,依赖传递特性会很方便帮助我们下来它相关的依赖,而不必有时会因为引入jar有问题而烦恼,但是也有弊端,存在一些不必要的依赖,可能会造成冲突。

    【scope依赖冲突】

    假设有如下依赖关系:

    • A项目------>依赖于L.jar1.0版本
    • B项目------->依赖于L.jar2.0版本
    • C项目-------->既依赖A也依赖B

    那么传递给C的L.jar是哪一个版本的包呢?

    A和L的关系叫做直接依赖,C和L的依赖叫做间接依赖。当我们有了间接依赖之后,我们先声明哪个依赖,就会用哪个依赖。比如userService先依赖于user-core(先写),再依赖于user-log(后写),user-core的log包是1.0.4的版本,user-log依赖的log包是1.2.7版本,则传到userService的log包就是user-core的log包(1.0.4版本)。

    但是user-core的commons-logging包是1.0.4的版本,user-log依赖的commons-logging包是1.1.1版本,但传到userService的log包就是user-log的log包(1.1.1版本),这是为什么呢?打开依赖关系库发现commons-logging是dbunit的间接依赖:

    所以我们的user-core和commons-logging是间接依赖的关系:commons-logging——>dbunit——>user-core;而user-log中是:commons-logging——>user-log,依赖关系比user-log少一级。

    总结:当依赖级别相同的时候,哪个先写就先用哪个;当依赖级别不同的时候,用级别/层次最短的那一个,也就是短路优先。

    【依赖排除】

    依赖排除的特性也是为了解决依赖冲突的一个方法,<exclusions>标签能很方便去除依赖传递过程中不必要的依赖。

    <dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-test</artifactId>  
        <version>4.2.2.RELEASE</version>  
        <!-- 依赖排除 -->  
        <exclusions>  
            <exclusion>  
                <groupId>commons-logging</groupId>  
                <artifactId>commons-logging</artifactId>  
            </exclusion>  
        </exclusions>  
    </dependency> 
    

    3. 插件

    Maven本质上是一个插件框架,它主要的任务都是由插件来完成。定位到:%本地仓库%\org\apache\maven\plugins,可以看到一些下载好的插件:

    Maven的生命周期是抽象的,实际需要插件来完成任务,这一过程是通过将插件的目标(goal)绑定到生命周期的具体阶段(phase)来完成的。就是说插件目标有一下两种方式被执行:

    • 通过直接调用的方式(也就是“plugin:goal”的方式)在生命周期阶段外执行。
    mvn [plugin-name]:[goal-name]
    

    例如,一个 Java 项目可以使用 Maven 编译器插件来编译目标,通过运行以下命令编译:

    mvn compiler:compile
    
    • 通过绑定到生命周期阶段,而在生命周期阶段执行时被调用
      如:将maven-compiler-plugin插件的compile目标绑定到default生命周期的compile阶段,完成项目的源代码编译:

    相关文章

      网友评论

          本文标题:pom.xml

          本文链接:https://www.haomeiwen.com/subject/uofttxtx.html