Maven基础知识学习笔记

1、什么是Maven

         Apache Maven是一个项目管理工具,它包含了一个项目对象模型(Project Object Model),一个标准几何,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

2、什么是pom 

    pom作为项目对象模型。

基本内容:

      POM包括了所有的项目信息。

      POM定义了最小的maven2元素,允许groupId,artifactId,version等所有需要的元素;groupId,,artifactId, version:描述了依赖的项目唯一标志

  • groupId:项目或者组织的唯一标志,并且配置时生成的路径也是由此生成,如com.taobao.cmp生成的相对路径为:/com/taobao/cmp
  • artifactId:groupId下的表示一个单独项目的唯一标识符,默认为jar
  • version:项目的版本
  • packaging:打包的机制,如pom, jar, maven-plugin, ejb, war, ear, rar, par

<groupId>com.taobao.XXXtest</groupId>

   <artifactId>XXX-qatest</artifactId>

   <version>1.0.0</version>

   <packaging>jar</packaging>

3POM中的关系: 

主要为依赖,合成,继承

3.1依赖关系(dependencies相关): 

Maven提供传递依赖:

A->B  B->C  C->D   则 A依赖D;

A->B->D1.0  A->D2.0 则 A依赖D2.0

A->E1.0  A->E2.0    则 A依赖E1.0

这种依赖方式遵循的原则:最近原则、最先原则(since maven 2.0.9)。

<dependencies>

    <dependency>

         <groupId>junit</groupId>

         <artifactId>junit</artifactId>

         <version>${junit.version}</version>

   </dependency>

</dependencies>

3.1.1依赖的范围(scope 

compile(缺省值 ),test,runtime,provided;

依赖范围(scope)主源码classpath可用测试源码classpath可用会被打包compile 缺省值TRUETRUETRUEtestFALSETRUEFALSEruntimeFALSETRUETRUEprovidedTRUETRUEFALSE

Junit包一般来说只有在运行测试的时候需要它,对上一个例子进行改进:

<dependencies>

    <dependency>

         <groupId>junit</groupId>

         <artifactId>junit</artifactId>

         <version>${junit.version}</version>

         <scope>test</scope>

   </dependency>

</dependencies>

再举个例子,在开发javaee应用的时候一定会用到servlet-api,它对于主源码和测试源码都是必要的,因为我们的代码中会引入servlet-api的包。但是,在打包的时候,将其放入WAR包就会有问题,因为web容器会提供servlet-api,如果我们再将其打包就会造成依赖冲突,解决方案如下:

<dependency>  

  <groupId>javax.servlet</groupId>  

  <artifactId>servlet-api</artifactId>  

  <version>2.4</version>  

  <scope>provided</scope>  

</dependency>

3.1.2依赖归类 

随着项目的增大,依赖越来越多。例如依赖了很多spring的jar:org.springframework:spring;org.springframework:spring-mock;org.springframework: spring-aspects,它们的groupId是相同的,artifactId不同,为了管理其版本,可以采用下面这种方式

<dependencies>

<dependency>

              <groupId>org.springframework</groupId>

              <artifactId>spring</artifactId>

              <version>${spring.version}</version>

           </dependency>

           <dependency>

              <groupId>org.springframework</groupId>

              <artifactId>spring-mock</artifactId>

              <version>${spring.version}</version>

              <scope>test</scope>

           </dependency>

           <dependency>

              <groupId>org.springframework</groupId>

              <artifactId>spring-aspects</artifactId>

              <version>${spring.version}</version>

           </dependency>

</dependencies>

<properties>  

            <spring.version>2.0.7</spring.version>  

</properties> 

这里定义了一个Maven属性,其名称为spring.version,值是2.0.7。在这个POM中,能用${spring.version}的方式来引用该属性。所有spring相关的依赖的version元素现在都成了${spring.version},当Maven运行的时候,它会自动用值2.0.7来替换这个引用。

当需要升级spring的时候,只要更改一个地方便可,而且现在能很高的保证所有的spring依赖包都是同一个版本

3.1.3分类器(classifier 

         GAV是Maven坐标最基本最重要的组成部分,但GAV不是全部。还有一个元素叫做分类器(classifier),90%的情况你不会用到它,但有些时候,分类器非常不可或缺。

         例如:当测试工程需要依赖一个war包时,pom文件不支持直接依赖war包,所以需要在测试工程里依赖war的地方加上<classifier>classes</classifier>,表示依赖编译好的文件。

<dependencies>

<dependency>

       <groupId>com.taobao.XXX</groupId>

       <artifactId>XXX-web</artifactId>

       <version>1.0.0-SNAPSHOT</version>

       <classifier>classes</classifier>

</dependency>

</dependencies>

注意到maven下载了一个名为XXX-web-1.0.0-SNAPSHOT-classes.jar的文件。其命名模式实际上是<artifactId>-<version>-<classifier>.<packaging>。

3.1.4依赖管理(dependencyManagement 

当只有一个Maven模块的时候,完全不需要看这个部分。

除测试工程和一些简单的工程中,一般都有很多Maven模块,而且往往这些模块有很多依赖是完全相同的,A模块有个对spring的依赖,B模块也有,它们的依赖配置一模一样,同样的groupId, artifactId, version,或者还有exclusions, classifer。这是一种重复,重复就意味着潜在的问题,Maven提供的dependencyManagement就是用来消除这种重复的。

正确的做法是:

1. 在父模块中使用dependencyManagement配置依赖

2. 在子模块中使用dependencies添加依赖

dependencyManagement实际上不会真正引入任何依赖,dependencies才会。但是,当父模块中配置了某个依赖之后,子模块只需使用简单groupId和artifactId就能自动继承相应的父模块依赖配置。

父模块配置:

<dependencyManagement>

       <dependencies>

           <!–=====***=====–>

           <dependency>

              <groupId>com.taobao.common.***</groupId>

              <artifactId>common-***</artifactId>

              <version>1.2.3</version>

           </dependency>

        </dependencies>

</dependencyManagement>

         子模块配置:

    <dependencies>

       <dependency>

           <groupId>com.taobao.common.***</groupId>

           <artifactId>common-***</artifactId><!—父模块中已经设置了版本,这里不需要设置version–>

        </dependency>

    </dependencies>

3.1.5独占性  

由于Maven提供传递依赖,这样造成一个项目中,引用了同一jar包的不同版本,造成jar包冲突。解决办法:使用exclusion:

<dependency>

           <groupId>com.taobao.XXX</groupId>

           <artifactId>XXX-biz</artifactId>

           <version>1.0.0-SNAPSHOT</version>

           <exclusions>

              <exclusion>

                  <groupId>dbunit</groupId>

                  <artifactId>dbunit</artifactId>

              </exclusion>

           </exclusions>

</dependency>

引用XXX-biz jar包,不引用 dbunit jar包

3.2合成(或者多个模块)关系: 

一个项目有多个模块,也叫做多重模块,或者合成项目。

<modules>

        <module>XXX-biz</module>

        <module>XXX-web</module>

</modules>

3.3继承关系: 

Maven 提供了强大的项目继承。以下面的配置为例,此时XXX-biz中使用和父模块相同的groupId

<parent>

       <groupId>com.taobao.XXX</groupId>

       <artifactId>XXX</artifactId>

       <version>1.0.0-SNAPSHOT</version>

    </parent>

   <artifactId>XXX-biz</artifactId>

    <version>1.0.0-SNAPSHOT</version>

原文地址:https://www.cnblogs.com/danghuijian/p/4400054.html