Maven使用手册

前言:背景介绍

  1. Maven是什么?

如果没有Maven,你可能不得不经历下面的过程:

  • 如果使用了spring,去spring的官网下载jar包;如果使用hibernate,去hibernate的官网下载Jar包;如果使用Log4j,去log4j的官网下载jar包.....
  • 当某些jar包有依赖的时候,还要去下载对应的依赖jar包
  • 当jar包依赖有冲突时,不得不一个一个的排查
  • 执行构建时,需要使用ant写出很多重复的任务代码
  • 当新人加入开发时,需要拷贝大量的jar包,然后重复进行构建
  • 当进行测试时,需要一个一个的运行....检查

 

有了Maven,它提供了三种功能:

  • 依赖的管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要写入这些依赖属性,就会自动下载并管理jar包。
  • 项目的构建:内置很多的插件与生命周期,支持多种任务,比如校验、编译、测试、打包、部署、发布...
  • 项目的知识管理:管理项目相关的其他内容,比如开发者信息,版本等等

Maven项目的结构和内容在一个XML文件中声明,pom.xml 项目对象模型(POM,Project-Object-Model),这是整个Maven系统的基本单元。

 

2、Maven如何管理jar包

关于jar包的坐标, maven是通过groupId,artifactId,以及version确定一个唯一的jar包。

例如,最常使用的Junit的声明就是如下:

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

首先先来说说Maven下载jar包的过程:

在Maven中会涉及到几种仓库:

  • 工作空间,即我们的项目工程,这里面可能会放着pom.xml文件,这个pom.xml就是maven的配置文件
  • 本地仓库,本地仓库用于存放jar包,其实Jar包并不是直接放入工作空间的,它是存放在本地仓库。默认的文件夹是 ".m2" 目录。,然后在执行发布打包的时候,添加依赖路径

 

  • 私库:私库是使用者自己搭建的maven仓库,用于缓解频繁从外网下载jar包资源的压力。而且使用私库作为缓存层,也相对安全一些。(一般公司都会有自己的Maven私服(采用Nexus搭建),它会与中央仓库进行index同步)
  • 共享仓库:Maven中央仓库或者一些常用的镜像网站都属于这。Maven中央存储库 https://repo1.maven.org/maven2/ (查询三方组件时可用https://search.maven.org)

 

3、Apache Maven 是做什么用的?

Maven 是一个项目管理和构建自动化工具。但是对于我们

程序员来说,我们最关心的是它的项目构建功能。Maven 使用约定优于配置的原则 。它要求在没有定制之前,所有的项目都有如下的结构:

${basedir}

存放 pom.xml和所有的子目录

${basedir}/src/main/java

项目的 java源代码

${basedir}/src/main/resources

项目的资源配置,比如说 property文件

${basedir}/src/test/java

项目的测试类,比如说 JUnit代码

${basedir}/src/test/resources

测试使用的资源

一个 maven 项目在默认情况下会产生 JAR 文件(也可配置生成war等),另外 ,编译后 的 classes 会放在 ${basedir}/target/classes 下面, JAR 文件会放在 ${basedir}/target 下面。

 

  • Maven基本操作

一些基本的操作,编译,构建,单元测试,安装,网站生成和基于Maven部署项目。

使用Maven构建项目

"mvn clean package" 来构建项目

使用Maven清理项目

"mvn clean" 来清理项目

使用Maven运行单元测试

"mvn clean test" 来执行单元测试

将项目安装到Maven本地资源库

"mvn install" 打包和部署项目到本地资源库

生成基于Maven的项目文档站点

"mvn site" 来为您的项目生成信息文档站点

使用"mvn site-deploy"部署站点(WebDAV例子)

"mvn site-deploy" 通过WebDAV部署自动生成的文档站点到服务器

部署基于Maven的war文件到Tomcat (一般结合jenkins使用)

"mvn tomcat:deploy" 以 WAR 文件部署到 Tomcat

 

参考学习网站推荐:

http://www.yiibai.com/maven/

http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-1-406235-zhs.html

http://www.cnblogs.com/xing901022/p/5024357.html

 

学习书籍PDF推荐:https://pan.baidu.com/s/1gdu1rDD

 

一、环境准备:Maven,Eclipse-Maven-Plugin

  1. Maven下载: http://maven.apache.org/download.cgi ,解压即可。然后配置M2_HOME以及Path环境变量。Maven默认下载的jar包放在用户目录下的 .m2目录(注意windows默认当成隐藏目录). 测试:打开cmd输入mvn –v看是否安装成功

    %M2_HOME%\bin

  2. Eclipse-Maven-Plugin:在高版本Eclipse中其实内置了Maven插件

(此处低版本maven可选)然后在Window->Preference->Java->Installed JREs->Edit

在Default VM arguments中设置

-Dmaven.multiModuleProjectDirectory=$M2_HOME

 

然后配置maven取消勾选下载远程索引

二、Maven的生命周期与阶段

理解Maven核心概念博客:

http://www.cnblogs.com/holbrook/archive/2012/12/24/2830519.html

 

官方文档部分: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

https://maven.apache.org/ref/3.3.9/maven-core/lifecycles.html

 

Maven中有三大生命周期,他们相互独立,分别是:

1 clean 清理

2 default 构建

3 site 建站

一般来说,clean和default比较常用。

每个生命周期又有不同的阶段,阶段按顺序执行,并且可以指定执行结束的阶段。构建的时候,会依次从最上面的阶段执行到指定的那个阶段。

比如,clean有3个阶段:

1 pre-clean 执行清理前要完成的工作

2 clean 清理上一次构建生成的文件

3 post-clean 执行清理后需要完成的工作

当我们输入mvn clean的时候,执行的是pre-clean和clean两个阶段。

default的阶段比较多:

1 validate

2 initialize

3 generate-sources

4 process-sources

5 generate-resources

6 process-resources

7 compile

8 process-classes

9 generate-test-sources

10 process-test-sources

11 generate-test-resources

12 process-test-resources

13 test-compile

14 process-test-classes

15 test

16 prepare-package

17 package

18 pre-integration-test

19 integration-test

20 post-integration-test

21 verify

22 install

23 deploy

看名字大概就能理解,当执行mvn install的时候,实际会执行validate-->initialize-->...-->verify-->install等二十几个阶段。

为了操作方便,不同的声明周期可以在一起执行,比如mvn clean install,会先执行clean的阶段,在执行install的阶段。

 

三、ProjectObjectModel文件介绍

如果使用过Ant都知道Ant是通过build.xml执行构建任务的,Maven中是通过pom.xml来执行任务。

POM,project object model,即项目对象模型,它通过这个pom.xml描述一个项目的构建以及信息。

 

<?<?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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.xinoo.test</groupId>

<artifactId>first-maven</artifactId>

<version>1.0-SNAPSHOT</version>

<name>First Maven Project</name>

</project>

第一行指定了文档的XML版本和编码

第二行即每个pom.xml的核心元素——project

project下面有几个子元素,这几个子元素一般是每个项目都会使用到的:

1 modelVersion这个元素指定了POM的版本,Maven2或者Maven3 都只能是4.0.0

2 groupId 是项目组的ID,一般是com.公司组织名.项目名

3 artifactId 是该项目在项目组中的ID,比如当前的项目是项目组的一个代理项目,就可以叫做myproxy

4 version 是项目的版本号,用于维护项目的升级和发布

5 name 一般没有实际的用处,只是用于标识该项目

比较重要的参数是 groupId、artifactId、version,这三个属性确定唯一的一个项目。

 

1、pom文件的变量:

pom.xml隐式变量

env

env 变量暴露了你操作系统或者shell 的环境变量。例如,在Maven POM 中一个对${env.PATH}的引用将会被${PATH}环境变量替换(或者Windows 中的%PATH%)。

 

project

project 变量暴露了POM。你可以使用点标记(.)的路径来引用POM 元素的值。例如,在本节中我们使用过groupId 和artifactId 来设置构建配置中的finalName 元素。这个属性引用的语法是:

${project.groupId}-${project.artifactId}。

 

settings

settings 变量暴露了Maven settings 信息。可以使用点标记(.)的路径来引用settings.xml 文件中元素的值。例如,${settings.offline}会引用~/.m2/settings.xml 文件中offline 元素的值。

 

Java 系统属性

所有可以通过java.lang.System 中getProperties()方法访问的属性都被暴露成POM 属性。一些系统属性的例子是:${user.name},${user.home},${java.home},和${os.name}。一个完整的系统属性列表可以在java.lang.System 类的Javadoc 中找到。

 

自定义属性:

<properties>

<foo>bar</foo>

</properties>

 

2、依赖

会包含基本的groupId, artifactId,version等元素,根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个依赖。

下面详细讲解每个依赖可以包含的元素:

groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖

type: 依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar,war

scope: 依赖的范围,

  • compile 编译,测试,运行都有效。默认的依赖范围。
  • test 测试,对于编译测试有效,对于运行无效。如:servlet-api,junit
  • runtime 运行,对于测试和运行均有效。但在编译时无效。如 JDBC。
  • provided 编译,测试,如 ServletAPI。
  • system 编译,测试,依赖于系统变量。

optional: 标记传递依赖是否可选

exclusions: 用来排除传递性依赖

classifier代表附属构建如javadoc,source等

大部分依赖声明只包含基本坐标。

 

依赖的传递性:

依赖是具有传递性的,例如 Project A 依赖于 Project B,B 依赖于 C,那么 B 对 C 的依赖关系也会传递给 A,如果我们不需要这种传递性依赖,也可以用 <optional> 去除这种依赖的传递,如清单 5。

清单 5. 选择性依赖

<dependency>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

<version>1.1.1</version>

<optional>true<optional>

</dependency>

假设第三方的 jar 包中没有使用 <optional> 来去除某些依赖的传递性,那么可以在当前的 POM 文件中使用 <exclusions> 元素声明排除依赖,exclusions 可以包含一个或者多个 exclusion 子元素,因此可以排除一个或者多个传递性依赖。如清单 6。

清单 6. 排除依赖

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

 

  1. Maven 插件

 

插件列表:http://maven.apache.org/plugins/index.html

Maven 本质上是一个插件框架,它的核心并不执行任何具体的构建任务,仅仅定义了抽象的生命周期,所有这些任务都交给插件来完成的。每个插件都能完成至少一个任务,每个任务即是一个功能,将这些功能应用在构建过程的不同生命周期中。

常用插件:

  • java编译插件:

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>3.3</version>

                <configuration>

                    <source>${java-version}</source>

                    <target>${java-version}</target>

                    <encoding>${project-encoding}</encoding>

                </configuration>

            </plugin>

        </plugins>

以上的这个就是java编译插件。

 

  • war包打包插件:

    <plugin>

                    <groupId>org.apache.maven.plugins</groupId>

                    <artifactId>maven-war-plugin</artifactId>

                    <version>2.6</version>

                </plugin>

                <plugin>

                    <groupId>org.apache.maven.plugins</groupId>

                    <artifactId>maven-compiler-plugin</artifactId>

                    <version>3.3</version>

                    <configuration>

                        <source>${java-version}</source>

                        <target>${java-version}</target>

                        <encoding>${project-encoding}</encoding>

                        <compilerArguments>

                            <extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>

                        </compilerArguments>

                    </configuration>

                </plugin>

     

  • Jar包打包插件:

    <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-shade-plugin</artifactId>

                <version>1.7</version>

                <executions>

                    <execution>

                        <phase>package</phase>

                        <goals>

                            <goal>shade</goal>

                        </goals>

                        <configuration>

                            <transformers>

                                <transformer

                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

                                    <mainClass>com.css.sword.sitesync.App</mainClass>

                                </transformer>

                                <!-- <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">

                                    <resource>applicationContext.xml</resource> </transformer> -->

                            </transformers>

                        </configuration>

                    </execution>

                </executions>

            </plugin>

 

  1. 模块聚合与继承

现实中一个项目往往是由多个 project 构成的,在进行构建时,我们当然不想针对多个 project 分别执行多次构建命令,这样极容易产生遗漏也会大大降低效率。Maven 的聚合功能可以通过一个父模块将所有的要构建模块整合起来,将父模块的打包类型声明为 POM,通过 <modules> 将各模块集中到父 POM 中。如清单 7,其中 <module></module> 中间的内容为子模块工程名的相对路径。

清单 7. 聚合

<modules>

<module>../com.dugeng.project1</module>

<module>../com.dugeng.project2</module>

</modules>

在面向对象的编程中我们学会了继承的概念,继承是可重用行即消除重复编码的行为。Maven 中继承的用意和面向对象编程中是一致的。与聚合的实现类似,我们通过构建父模块将子模块共用的依赖,插件等进行统一声明,在聚合和继承同时使用时,我们可以用同一个父模块来完成这两个功能。

例如将 com.dugeng.parent 这个模块声明为 project1 和 project2 的父模块,那么我们在 project1 和 2 中用如下代码声明父子关系,如清单 8:

清单 8. 继承

<parent>

<groupId>com.dugeng.mavenproject</groupId>

<artifactId>com.dugeng.parent</artifactId>

<version>0.0.1-SNAPSHOT</version>

<relativePath>../com.dugeng.parent/pom.xml</relativePath>

</parent>

由于父模块只是用来声明一些可共用的配置和插件信息,所以它也像聚合模块一样只需要包括一个 POM 文件,其它的项目文件如 src/main/java 是不需要的。

聚合和继承存在一些共性和潜在的联系,在实际的应用中,经常将聚合模块的父模块和继承的父模块定义为同一个。

 

  1. 分环境配置打包:

当我们存在多个环境需要部署时,我们不需要每次部署时都去改变配置,只需要配置一次即可。

    <profiles>

        <profile>

            <!-- 本地开发环境 -->

            <id>development</id>

            <properties>

                <profile.env>development</profile.env>

            </properties>

            <activation>

                <activeByDefault>true</activeByDefault>

            </activation>

        </profile>

        <profile>

            <!-- 测试环境 -->

            <id>test</id>

            <properties>

                <profile.env>test</profile.env>

 

            </properties>

        </profile>

        <profile>

            <!-- 生产环境 -->

            <id>production</id>

            <properties>

                <profile.env>production</profile.env>

 

            </properties>

        </profile>

    </profiles>

    <build>

        <finalName>${base-name}</finalName>

        <resources>

            <resource>

                <directory>${project.basedir}/src/main/resources</directory>

                <!-- 资源根目录排除各环境的配置,使用单独的资源目录来指定 -->

                <excludes>

                    <exclude>test/*</exclude>

                    <exclude>production/*</exclude>

                    <exclude>development/*</exclude>

                </excludes>

            </resource>

            <resource>

                <directory>${project.basedir}/src/main/resources/${profile.env}</directory>

            </resource>

        </resources>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>3.3</version>

                <configuration>

                    <source>${java-version}</source>

                    <target>${java-version}</target>

                    <encoding>${project-encoding}</encoding>

                </configuration>

            </plugin>

 

        </plugins>

 

比如我想根据测试环境打包,执行 mvn –Ptest clean package即可

 

四、Nexus仓库搭建:(开发人员不需要搭建)

参考:http://www.cnblogs.com/luotaoyeah/p/3791966.html

http://blog.csdn.net/shenshen123jun/article/details/9084293

http://blog.csdn.net/liujiahan629629/article/details/39272321

注意:nexus无法更新索引问题解决:(https://issues.sonatype.org/browse/NEXUS-10233

修改conf/nexus.properties文件,添加:

org.sonatype.nexus.proxy.maven.routing.Config.prefixFileMaxSize=500000

如出现刷新索引时出现

There was an error communicating with the server: request timed out.

解决(https://issues.sonatype.org/browse/NEXUS-5823):

修改administration/server UI time 默认为60s

 

五、向Nexus私服发布

发布命令mvn clean deploy

条件:默认发布用户名和密码: deployment deployment123

配置mavensetting.xml配置:

<servers>    

    <server>

<id>releases</id>

<username>deployment</username>

<password>admin123</password>

</server>

<server>

<id>snapshots</id>

<username>deployment</username>

<password>admin123</password>

</server>

</servers>

pom.xml配置:

        <distributionManagement>

        <repository>

            <id>releases</id>

            <name>deployment</name>

            <url>http://localhost:8081/nexus/content/repositories/releases</url>

        </repository>

        <snapshotRepository>

            <id>snapshots</id>

            <name>deployment</name>

            <url>http://localhost:8081/nexus/content/repositories/snapshots</url>

        </snapshotRepository>

 

    </distributionManagement>然后运行发布

mvn clean deploy

在控制台发布成功

然后进入到私服上的仓库中,看一下是否存在刚刚发布的项目

五、新建Maven项目

常用的有两种,一种是jar包形式的为maven-archetype-quickstart,一种是war形式的为maven-archetype-webapp

(如果是依赖于war包的情形(其它情形不必理会):新建运行项目的时候需要运clean package,然后它会自动在target下生成解压的war与当前项目代码合并的项目。

添加至eclipse servers需要配置的deployment assembly如下:

各种配置见pom示例文件夹

附录:pom.xml完整一级元素列表

<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<! – The Basics – >

<groupId> … </groupId>

<artifactId> … </artifactId>

<version> … </version>

<packaging> … </packaging>

<dependencies> … </dependencies>

<parent> … </parent>

<dependencyManagement> … </dependencyManagement>

<modules> … </modules>

<properties> … </properties>

<! – Build Settings – >

<build> … </build>

<reporting> … </reporting>

<! – More Project Information – >

<name> … </name>

<description> … </description>

<url> … </url>

<inceptionYear> … </inceptionYear>

<licenses> … </licenses>

<organization> … </organization>

<developers> … </developers>

<contributors> … </contributors>

<! – Environment Settings – >

<issueManagement> … </issueManagement>

<ciManagement> … </ciManagement>

<mailingLists> … </mailingLists>

<scm> … </scm>

<prerequisites> … </prerequisites>

<repositories> … </repositories>

<pluginRepositories> … </pluginRepositories>

<distributionManagement> … </distributionManagement>

<profiles> … </profiles>

</project>

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值