• Maven学习笔记


    1.Maven安装

    Maven和ant同为apache出版的构建工具,与gradle是一类东西,与C语言中的make是同一类产品。从apache官网上下载maven的zip安装包,解压即可使用,需要把解压后的bin目录添加到环境变量中去。
    Eclipse是自带maven的,如果不想使用eclipse的内置maven,可以在preference->maven->installations中进行设置。

    2.最简的pom.xml文件

    pom的意思是project object model项目对象模型。

    <project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.jenkov</groupId>
        <artifactId>java-web-crawler</artifactId>
        <version>1.0.0</version>
    </project>
    

    其中,modelVersion表示正在使用的pom模型版本,groupId表示项目名称,artifactId表示模块名称,一个项目可以包含多个模块。

    3.pom的继承

    一个pom可以继承自父pom,它可以继承父pom的dependencies,要想让一个pom继承另一个pom,可以使用parent标签来声明父pom。

    <project xmlns=”http://maven.apache.org/POM/4.0.0″
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
    xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd”>
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>my-parent</artifactId>
            <version>2.0</version>
            <relativePath>../my-parent</relativePath>
        </parent>
        <artifactId>my-project</artifactId>
        ...
    </project>
    

    子pom中的值会覆盖父pom中的值.因为pom的继承关系,最终的pom成为有效pom,可以通过mvn help:effective-pom命令来查看最终的pom。
    每一个pom.xml默认继承super pom,super pom内容如下:

    <project>
      <modelVersion>4.0.0</modelVersion>
      <name>Maven Default Project</name>
    
      <repositories>
        <repository>
          <id>central</id>
          <name>Maven Repository Switchboard</name>
          <layout>default</layout>
          <url>http://repo1.maven.org/maven2</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
     
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>Maven Plugin Repository</name>
          <url>http://repo1.maven.org/maven2</url>
          <layout>default</layout>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <releases>
            <updatePolicy>never</updatePolicy>
          </releases>
        </pluginRepository>
      </pluginRepositories>
     
      <build>
        <directory>target</directory>
        <outputDirectory>target/classes</outputDirectory>
        <finalName>${artifactId}-${version}</finalName>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <sourceDirectory>src/main/java</sourceDirectory>
        <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
        <testSourceDirectory>src/test/java</testSourceDirectory>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <directory>src/test/resources</directory>
          </testResource>
        </testResources>
      </build>
     
      <reporting>
        <outputDirectory>target/site</outputDirectory>
      </reporting>
     
      <profiles>
        <profile>
          <id>release-profile</id>
     
          <activation>
            <property>
              <name>performRelease</name>
            </property>
          </activation>
     
          <build>
            <plugins>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
     
                <executions>
                  <execution>
                    <id>attach-sources</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
     
                <executions>
                  <execution>
                    <id>attach-javadocs</id>
                    <goals>
                      <goal>jar</goal>
                    </goals>
                  </execution>
                </executions>
              </plugin>
              <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
     
                <configuration>
                  <updateReleaseInfo>true</updateReleaseInfo>
                </configuration>
              </plugin>
            </plugins>
          </build>
        </profile>
      </profiles>
     
    </project>
    

    4.maven的配置

    maven配置文件中的配置相当于全局配置,对于所有的pom.xml都是有效的。在配置文件settings.xml中可以配置:

    • 本地仓库的路径,默认为~/.m2
    • 当前编译选项
    • 其他一些配置
      settings.xml有两个:一个是%Maven_Home%/conf/settings.xml,另一个是~/.m2/settings.xml。后者会覆盖前者的设置。

    5.运行maven

    maven构建项目有三个概念:生命周期,阶段,目标.maven内置三个生命周期,一个生命周期包括多个阶段,一个阶段包括多个目标。
    运行maven只需要输入mvn命令,maven就会自动查找当前目录下的pom.xml并按照要求进行执行。
    mvn命令还可以带一些参数,参数包括阶段和目标。
    例如install就是一个阶段,它是在target目录中生成jar文件并将jar文件复制到maven本地仓库中去(即~/。m2目录中)。执行install阶段就会默认把install之前的阶段全部执行,命令为mvn install
    可以向mvn传递多个参数,表示执行多个阶段,例如mvn clean install,先进行clean把target中生成的jar删除,然后再执行install。
    可以让mvn执行某个目标,命令形式为mvn 阶段名:目标名,例如mvn dependencies:copy-dependencies

    6.maven项目的目录结构

    maven遵循”约定大于配置”原则,对目录有默认的组织,如果不按照默认的来,就需要指明src目录,target目录等。

    - src
      - main
        - java
        - resources
        - webapp
      - test
        - java
        - resources
    - target
    

    target目录是maven创建的,执行mvn clean命令之后target目录被清空。

    7.项目依赖

    项目A依赖项目B,项目B依赖项目C。众多的项目形成一个有向无环图(DAG),每一个项目相当于一个结点,每一条有向边表示一个依赖关系。如果要使用B.jar,不下载C.jar肯定会报错。使用maven,就可以自动推导出项目所依赖的全部jar包,解决项目依赖问题是maven的重要作用之一,maven会自动下载所需jar包到本地仓库中。使用dependency的一个例子如下所示:

    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
       http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.jenkov.crawler</groupId>
        <artifactId>java-web-crawler</artifactId>
        <version>1.0.0</version>
    
        <dependencies>
            <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.7.1</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.8.1</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
        <build>
        </build>
    </project>
    

    有的时候,指定的依赖在Maven的中央仓库里没有。你可以直接下载这些依赖,然后放到Maven的本地仓库。这些依赖必须放到与groupId、 artifactId和version匹配的子目录中。用/替换所有的点(.)并且使用/分隔groupId、artifactId和version,这就是与该依赖匹配的子目录。
    上面示例中的两个依赖将会被放到以下子目录中:
    MAVEN_REPOSITORY_ROOT/junit/junit/4.8.1
    MAVEN_REPOSITORY_ROOT/org/jsoup/jsoup/1.7.1
    Maven仓库分为三种:本地仓库(即~/.m2),远程仓库(自己建立的maven服务器),中心仓库.

    8.外部依赖

    有时只有一个jar包而没有它的groupId和artifactId,并且三种maven仓库中都没有这个jar包项目,但当前项目依赖这个jar包,这种依赖叫做外部依赖,可以用如下配置指定外部依赖。

    <dependency>
      <groupId>mydependency</groupId>
      <artifactId>mydependency</artifactId>
      <scope>system</scope>
      <version>1.0</version>
      <systemPath>${basedir}warWEB-INFlibmydependency.jar</systemPath>
    </dependency>
    

    这种方式需要在每一个maven工程的pom.xml中这么写,这样岂不是十分麻烦。一种解决方案是把第三方jar包安装到本地maven仓库中去。
    mvn install:install-file -Dfile= -DgroupId= -DartifactId= -Dversion= -Dpackaging=
    在这个命令中,需要手动提供groupIdartifactId等,(groupId,artifactId,version)三元组决定了一个jar包的坐标,groupId是作者信息,artifactId是作品名称,version是作品版本号,packaging是打包类型,可以取值war,jar等。如果第三方jar包有相应的pom.xml,则不必提供groupIdartifactId等信息,因为它们都在pom.xml里面进行了描述。可以使用如下命令:mvn install:install-file -Dfile= -DpomFile=

    例如,如下命令安装com.oracle的ojdbc14。

    mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.1.0 -Dpackaging=jar -Dfile=ojdbc14.jar
    

    在maven中进行如下配置

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.2.0.1.0</version>
    </dependency>
    

    9.快照依赖

    快照依赖指的是那些还在开发中的依赖(jar包)。与其经常地更新版本号来获取最新版本,不如你直接依赖项目的快照版本。快照版本的每一个build版本都会被下载到本地仓库,即使该快照版本已经在本地仓库了。总是下载快照依赖可以确保本地仓库中的每一个build版本都是最新的。
    在pom文件的最开头(设置groupId和artifactId的地方),在版本号后追加-SNAPSHOT,则告诉Maven你的项目是一个快照版本。如:
    <version>1.0-SNAPSHOT</version>
    可以看到加到版本号后的-SNAPSHOT。
    在配置依赖时,在版本号后追加-SNAPSHOT表明依赖的是一个快照版本。如:

    <dependency>
        <groupId>com.jenkov</groupId>
        <artifactId>java-web-crawler</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    

    追加在version后的-SNAPSHOT告诉Maven这是一个快照版本。
    可以在Maven配置文件中设置快照版本下载的频率。

    10.maven仓库

    Maven仓库就是存储jar包和一些元数据信息的目录。其中的元数据即pom文件,描述了该jar包属于哪个项目,以及jar包所需的外部依赖。该元数据信息使得Maven可以递归地下载所有的依赖,直到整个依赖树都下载完毕并放到你的本地仓库中。查找依赖时,首先是本地仓库,然后是中央仓库,最后,如果pom文件中配置了远程仓库,则会去远程仓库中查找。
    (1)本地仓库
    本地仓库默认路径为~/.m2,可以在%MAVEN_HOME%/conf/settings.xml中设置本地仓库路径

    <settings>
      <localRepository>
        d:datajavaproductsmaven
    epository
      </localRepository>
    </settings>
    

    可以通过mvn install命令构建自己的项目并安装到本地仓库中去。
    (2)中央仓库
    Maven的中央仓库由Maven社区提供。默认情况下,所有不在本地仓库中的依赖都会去这个中央仓库查找。然后Maven会将这些依赖下载到你的本地仓库。访问中央仓库不需要做额外的配置。
    (3)远程仓库
    远程仓库是位于web服务器上的一个仓库,Maven可以从该仓库下载依赖,就像从中央仓库下载依赖一样。远程仓库可以位于Internet上的任何地方,也可以是位于本地网络中。
    远程仓库一般用于放置组织内部的项目,该项目由多个项目共享。比如,由多个内部项目共用的安全项目。该安全项目不能被外部访问,因此不能放在公开的中央仓库下,而应该放到内部的远程仓库中。
    远程仓库中的依赖也会被Maven下载到本地仓库中。
    可以在pom文件里配置远程仓库。将以下的xml片段放到属性之后:

    <repositories>
      <repository>
        <id>jenkov.code</id>
        <url>http://maven.jenkov.com/maven2/lib</url>
      </repository>
    </repositories>
    

    11. Maven插件

    使用Maven插件,可以向构建过程添加自定义的动作。创建一个简单的Java类,该类继承一个特殊的Maven类,然后为项目创建一个pom文件。该插件应该位于其项目下。

    12.maven构建生命周期,阶段,目标

    (1)生命周期
    Maven有三个内嵌的生命周期:

    • default
    • clean
    • site

    这三个生命周期是互不干扰的,default是默认生命周期,负责项目的编译和打包;clean是删除target目录中之前生成的.class和.jar等文件,site关注的是为项目生成文档,实际上site可以为项目生成一个网页式的文档。
    一个生命周期包含多个构建阶段,每个构建阶段又包括一系列目标。
    (2)构建阶段
    每一个构建生命期被分为一系列的构建阶段,构建阶段又被分为构建目标。因此,整个构建过程由一系列的构建生命期、构建阶段和构建目标组成。
    你可以执行一个构建生命期,如clean或site,一个构建阶段,如default生命期的install,或者一个构建目标,如dependency:copy-dependencies。注意:你不能直接执行default生命期,你需要指定default生命期中的一个构建阶段或者构建目标。
    当你执行一个构建阶段时,所有在该构建阶段之前的构建阶段(根据标准构建顺序)都会被执行。因此,执行install阶段,意味着所有位于install阶段前的构建阶段都会被执行,然后才执行install阶段。
    default生命期更多的关注于构建代码。由于你不能直接执行default生命期,你需要执行其中一个构建阶段或者构建目标。default生命期包含了相当多的构建阶段和目标,这里不会所有都介绍。最常用的构建阶段有:

    • validate 验证项目的正确性,以及所有必需的信息都是否都存在。同时也会确认项目的依赖是否都下载完毕。
    • compile 编译项目的源代码
    • test 选择合适的单元测试框架,对编译后的源码执行测试;这些测试不需要代码被打包或者部署。
    • package 将编译后的代码以可分配的形式打包,如Jar包。
    • install 将项目打包后安装到本地仓库,可以作为其它项目的本地依赖。
    • deploy 将最终的包复制到远程仓库,与其它开发者和项目共享。

    将构建阶段的名称作为参数传给mvn命令,就是执行该构建阶段,如:mvn package
    该示例执行package构建阶段,因此在Maven的构建阶段序列中所有位于该阶段之前的阶段也都会被执行。
    如果标准的Maven构建阶段和目标无法满足项目的需要,可以创建Maven插件增加你需要的构建功能。
    (3)构建目标
    构建目标是Maven构建过程中最细化的步骤。一个目标可以与一个或多个构建阶段绑定,也可以不绑定。如果一个目标没有与任何构建阶段绑定,你只能将该目标的名称作为参数传递给mvn命令来执行它。如果一个目标绑定到多个构建阶段,该目标在绑定的构建阶段执行的同时被执行。

    13. 传递性依赖

    传递性依赖是Maven2.0的新特性。假设你的项目依赖于一个库,而这个库又依赖于其他库。你不必自己去找出所有这些依赖,你只需要加上你直接依赖的库,Maven会隐式的把这些库间接依赖的库也加入到你的项目中。这个特性是靠解析从远程仓库中获取的依赖库的项目文件实现的。一般的,这些项目的所有依赖都会加入到项目中,或者从父项目继承,或者通过传递性依赖。
    传递性依赖的嵌套深度没有任何限制,只是在出现循环依赖时会报错。
    传递性依赖会导致包含库的依赖图增长的非常大。为了解决这个问题,Maven也提供了额外的机制,能让你指定哪些依赖会被包含:
    依赖调解 – 当项目中出现多个版本构件依赖的情形,依赖调解决定最终应该使用哪个版本。目前,Maven 2.0只支持“短路径优先”原则,意思是项目会选择依赖关系树中路径最短的版本作为依赖。当然,你也可以在项目POM文件中显式指定使用哪个版本。值得注意的是,在Maven2.0.8及之前的版本中,当两个版本的依赖路径长度一致时,哪个依赖会被使用是不确定的。不过从Maven 2.0.9开始,POM中依赖声明的顺序决定了哪个版本会被使用,也叫作”第一声明原则”。
    “短路径优先”意味着项目依赖关系树中路径最短的版本会被使用。例如,假设A、B、C之间的依赖关系是A->B->C->D(2.0)和A->E->(D1.0),那么D(1.0)会被使用,因为A通过E到D的路径更短。但如果你想要强制使用D(2.0),那你也可以在A中显式声明对D(2.0)的依赖。
    依赖管理 – 在出现传递性依赖或者没有指定版本时,项目作者可以通过依赖管理直接指定模块版本。之前的章节说过,由于传递性依赖,尽管某个依赖没有被A直接指定,但也会被引入。相反的,A也可以将D加入元素中,并在D可能被引用时决定D的版本号。
    依赖范围 – 你可以指定只在当前编译范围内包含合适的依赖。
    排除依赖 – 如果项目X依赖于项目Y,项目Y又依赖项目Z,项目X的所有者可以使用”exclusion”元素来显式排除项目Z。
    可选依赖 – 如果项目Y依赖项目Z,项目Y的所有者可以使用”optional”元素来指定项目Z作为X的可选依赖。那么当项目X依赖项目Y时,X只依赖Y并不依赖Y的可选依赖Z。项目X的所有者也可以根据自己的意愿显式指定X对Z的依赖。(你可以把可选依赖理解为默认排除)。
    下面对依赖范围进行详细说明.
    依赖范围会影响传递性依赖,同时也会影响项目构建任务中使用的classpath。

    Maven有以下6种依赖范围:

    • compile
      这是默认范围。如果没有指定,就会使用该依赖范围。编译依赖对项目所有的classpath都可用。此外,编译依赖会传递到依赖的项目。
    • provided
      和compile范围很类似,但provided范围表明你希望由JDK或者某个容器提供运行时依赖。例如,当使用Java EE构建一个web应用时,你会设置对Servlet API和相关的Java EE APIs的依赖范围为provided,因为web容器提供了运行时的依赖。provided依赖只对编译和测试classpath有效,并且不能传递。
    • runtime
      runtime范围表明编译时不需要依赖,而只在运行时依赖。此依赖范围对运行和测试classpath有效,对编译classpath无效。
    • test
      test范围表明使用此依赖范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。
    • system
      系统范围与provided类似,不过你必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven也不会去仓库中寻找它。
    • import(Maven2.0.9及以上)
      import范围只适用于pom文件中的部分。表明指定的POM必须使用部分的依赖。因为依赖已经被替换,所以使用import范围的依赖并不影响依赖传递。

    14. 使用镜像中心仓库

    用maven下载好慢啊,快试试阿里云镜像吧!修改$MAVEN_HOME/conf/settings.xml

     <!-- 阿里云仓库 -->
    <mirror>
        <id>alimaven</id>
        <mirrorOf>central</mirrorOf>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
    

    在IntelliJ中,默认Maven配置从~/.m2/settings.xml中读取。虽然上面改对了,但是IDE不知道去哪里读取settings.xml,所以需要在Settings/Build Tools/Maven中进行设置。

  • 相关阅读:
    Java 1 (JVM、JRE、JDK之间的关系)
    Java 0 (jdk下载安装及环境配置)
    推荐之链接
    idea 2019激活码
    Mock数据使用的Util
    mybatis慢查询配置
    logback参考配置
    Linux网络实时监控配置
    jmeter插件JMeterPlugins-Standard 压力测试
    ZoneDateTime 转换Date
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6056705.html
Copyright © 2020-2023  润新知