maven的这些东西你都懂吗?

2018-08-27  本文已影响25人  ZMRWEGo

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文件的要求

节点 说明
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构建声明周期

三个关键字:

2.1 lifestyle

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

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仓库有三种类型:

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功能点来实现的。

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <encoding>UTF-8</encoding>    <!--配置资源文件编码-->
    </configuration>
</plugin>
<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>
<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>
<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>
<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>
<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>
    <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>
上一篇下一篇

猜你喜欢

热点阅读