美文网首页
maven的这些东西你都懂吗?

maven的这些东西你都懂吗?

作者: ZMRWEGo | 来源:发表于2018-08-27 10:42 被阅读25次

    Maven[ˈmevən]能帮你构建工程,管理jar包,编译代码,还能帮你自动运行单元测试,打包,生成报表,甚至能帮你部署项目,生成Web站点, 为开发者提供了一套完整的构建生命周期框架。开发团队几乎不用花多少时间就能够自动完成工程的基础构建配置,因为 Maven 使用了一个标准的目录结构和一个默认的构建生命周期。

    1. POM文件

    Maven 工程结构和内容被定义在一个 xml 文件中 pom.xml,是 Project Object Model (POM) 的简称,此文件是整个 Maven 系统的基础组件。POM 它放在工程根目录下,包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程。也包含了目标和插件。当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标。下面是一个简单的pom文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <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>Hust</groupId>
    <artifactId>Gongmei</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    
    <name>Gongmei Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <lucene.version>6.0.1</lucene.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!--<scope>provided</scope>-->
        </dependency>
     </dependencies>
    <build>
        <!--解决IDEA自动重置LanguageLevel和JavaCompiler版本的问题-->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
        <finalName>cloud</finalName>
    </build>
    </project>
    

    POM文件的要求

    • 每个工程应该只有一个 POM 文件。
    • 所有的 POM 文件需要 project 元素和三个必须的字段:groupId, artifactId,version。表达当前工程的信息
    • 在仓库中的工程标识为 groupId:artifactId:version
    节点 说明
    groupID 这是工程组的标识。它在一个组织或者项目中通常是唯一的。例如,一个银行组织 com.company.bank 拥有所有的和银行相关的项目。
    artifactId 这是工程的标识。它通常是工程的名称。例如,消费者银行。groupId 和 artifactId 一起定义了 artifact 在仓库中的位置。
    version 这是工程的版本号。在 artifact 的仓库中,它用来区分不同的版本。例如:com.company.bank:consumer-banking:1.0 com.company.bank:consumer-banking:1.1.
    properties 项目中的配置文件。指明项目中一些配置,例如字体编码以及版本号等
    dependencies 项目中的依赖文件。即项目中需要引入的jar包。
    plugins maven插件。Maven 实际上是一个依赖插件执行的框架,每个任务实际上是由插件完成。Build plugins:在构建时执行;Reporting plugins:在网站生成过程中执行

    2. Maven构建声明周期

    三个关键字:

    • lifecycle 生命周期
    • phase 阶段
    • goal 目标
      lifecycle 中包含phase ,phase 中包含goal 。

    2.1 lifestyle

    每个lifecycle 中都包含一个或多个phase 。通过 Maven 命令调用lifecycle中的phase时,该lifecycle中phase之前以及包括该phase在内的所有phase会被执行。Maven 有以下三个默认的生命周期:

    • clean 删除构建目录
    • build 构建应用
    • site 创建新的报告文档、部署站点

    2.2 phase

    执行phase实际执行的是goal。如果一个phase没有绑定goal,这个phase就不会被执行。每个phase定义了一个或多个goals ,其中的goals是顺序执行。一些phase默认已经绑定了一些goal。对于default lifecycle来说, 这些被绑定的goal并不完全相同,而是和packaging value相关。

    2.3 goal

    最终被执行的就是goal,goal与goal之间是独立的。因此单独执行一个goal不会导致其他goal被执行。
    e.g: mvn clean dependency:copy-dependencies package,maven会顺序执行这3个对象中包含的所有goal。

    3. Maven仓库

    Maven仓库有三种类型:

    • 本地(local)
    • 中央(central)
    • 远程(remote)

    3.1 本地仓库

    Maven 本地仓库保存你的工程的所有依赖(library jar、plugin jar 等)。当你运行一次 Maven 构建,Maven 会自动从中央库或远程库下载所有依赖的 jar 文件到本地仓库中。它避免了每次构建时都引用存放在远程机器上的依赖文件。
    Maven 本地仓库默认被创建在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。

      <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
       http://maven.apache.org/xsd/settings-1.0.0.xsd">
        <localRepository>C:/MyLocalRepository</localRepository>
      </settings>
    

    3.2 中央仓库

    Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。通俗一点说,就是一个网站,上面存放大量的库,项目中用到中央仓库的相关文件,就自动下载下来。可以在maven文件夹下的settings.xml中更改中央仓库的地址

    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mi rror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
    

    3.3 远程仓库

    如果 Maven 在中央仓库中也找不到依赖的库文件,它会停止构建过程并输出错误信息到控制台。可以在pom文件中指定远程仓库地址,那么Maven就会从该远程仓库下载依赖:

    <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.companyname.projectgroup</groupId>
     <artifactId>project</artifactId>
     <version>1.0</version>
       <dependencies>
      <dependency>
         <groupId>com.companyname.common-lib</groupId>
         <artifactId>common-lib</artifactId>
         <version>1.0.0</version>
      </dependency>
     </dependencies>
     <repositories>
      <repository>
         <id>companyname.lib1</id>
         <url>http://download.companyname.org/maven2/lib1</url>
      </repository>
      <repository>
         <id>companyname.lib2</id>
         <url>http://download.companyname.org/maven2/lib2</url>
      </repository>
     </repositories>
    </project>
    

    3.4 Maven依赖搜索顺序

    步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
    步骤 2 - 在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载到本地仓库中。
    步骤 3 - 如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
    步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库已被将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)

    4. Maven插件

    另外一种将goal绑定到phase的方法就是在project中使用plugin,一个plugin可能有一个或多个goal,其中每个goal代表一个plugin的功能。

    4.1 插件的使用

    一、插件通常提供了一个目标的集合,可以使用下面的方法使用:

    mvn  [plugin-name]:[goal-name]
    

    例如,一个 Java 工程可以使用 maven-compiler plugin 的 compile (goal) 编译,使用以下命令:

    mvn compiler:compile
    

    4.2 常用的插件列表

    插件 说明
    clean 构建之后清理目标文件(target文件),删除目标目录
    compiler 编译Java源文件
    surefile 运行junit单元测试,创建测试报告
    jar 从当前工程中构建jar文件
    war 从当前工程中构建war文件
    javadoc 为工程生成javadoc
    antrun 从构建过程的任意一个阶段中运行一个ant任务的集合

    5. Maven打包的详细过程

    mvn clean package
    

    执行详细过程如下:

    mvn打包过程
    从图中我们可以看到Maven的执行顺序:
    1、使用清理插件:maven-clean-plugin:2.5执行清理删除已有target目录(版本2.5)
    2、使用资源插件:maven-resources-plugin:2.6执行资源文件的处理(版本2.6)
    3、使用编译插件:maven-compiler-plugin:3.1编译所有源文件生成class文件至target\classes目录下(版本3.1)
    4、使用资源插件:maven-resources-plugin:2.6:testResource执行测试资源文件的处理(版本2.6)
    5、使用编译插件:maven-compiler-plugin:3.1:testCompile编译测试目录下的所有源代码(版本3.1)
    6、使用插件:maven-surefire-plugin:2.12.4运行测试用例(版本2.12.4);
    7、使用插件:maven-jar-plugin:2.4对编译后生成的文件进行打包,包名称默认为:artifactId-version,比如本例生成的jar文件:Gongmei-1.0-SNAPSHOT,包文件保存在target目录下,将该war包放入tomcat目录下的webapp中运行即可。

    备注:不管是compile、package还是install等前三个步骤都是必不可少的,即清理已有目录,处理资源文件、编译源文件。

    6. Maven常用插件

    maven默认会依据项目类型自动把构建时的各阶段(Lifecycle和phase)自动绑定到特定插件提供的功能(goal)点上。例如java项目编译(compile)阶段,实际上是调用了maven-compiler-plugin插件提供的compile功能点来实现的。

    • maven-resources-plugin 文件资源配置
    <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <configuration>
            <encoding>UTF-8</encoding>    <!--配置资源文件编码-->
        </configuration>
    </plugin>
    
    • maven-compiler-plugin 编译配置
      默认绑定到compile phase。maven2默认使用的是jdk5,jdk版本一般自己指定。
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
           <source>1.8</source>
           <target>1.8</target>
           <encoding>utf-8</encoding>   <!--指定utf-8版本-->
           <compilerArgument>-Xlint:none</compilerArgument>
           <compilerArguments>
                <extdirs>libs</extdirs>     <!--使用项目中的jar包-->
           </compilerArguments>
        </configuration>
     </plugin>
    
    • maven-surefire-plugin 单元测试
      默认绑定到test阶段
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <testFailureIgnore>true</testFailureIgnore>  <!--测试有失败用例时,是否继续构建-->
         <skipTests>true</skipTests>                  <!--是否跳过测试阶段,方式1-->
          <skip>true</skip>                            <!--是否跳过测试阶段,方式2-->
        </configuration>
    </plugin>
    
    • maven-jar-plugin 打jar包
      普通java项目(非web项目或其它类型的特殊项目),package阶段默认绑定的插件,能够将编译好的class和资源达成jar包,但不包含依赖
    <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-jar-plugin</artifactId>  
        <version>2.4</version>  
        <configuration>
        <excludes>  <!--打包时要排除的文件-->
            <exclude>agent.properties</exclude>  
        </excludes>
           <archive>  
               <manifest>  
                   <addClasspath>true</addClasspath>  
    <!--           <classpathPrefix>lib/</classpathPrefix>   -->
                   <mainClass>com.demo.HelloWorld</mainClass>  
                </manifest>  
             </archive>  
          </configuration>  
       </plugin>
    
    • maven-assembly-plugin 打包含依赖的全包
      在打包时,对jar包的打包形式进行自定义配置
    <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <descriptors>
                            <!--自定义配置文件-->
                            <descriptor>src/main/resources/package.xml</descriptor>
                        </descriptors>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    

    下面是具体的配置package.xml

    <assembly>
        <id>bin</id>
        <!-- 最终打包成一个用于发布的zip文件 -->
        <formats>
            <format>zip</format>
        </formats>
    
    • maven-war-plugin 打war包
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
       <configuration>
            <warName>${project.artifactId}</warName>
            <webResources>
              <resource>     <!--将额外的jar依赖打入war包-->
                  <directory>libs/</directory>
                  <targetPath>WEB-INF/lib</targetPath>
                  <includes>
                      <include>**/*.jar</include>
                  </includes>
               </resource>
            </webResources>
            <packagingExcludes>css/**,html/**</packagingExcludes>
        </configuration>
    </plugin>
    
    • maven-source-plugin 打包源码
        <plugin>        
         <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.1.2</version>
            <executions>
              <execution>
                <id>attach-sources</id>
                <phase>verify</phase>
                <goals>
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
    

    相关文章

      网友评论

          本文标题:maven的这些东西你都懂吗?

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