maven介绍

Maven基础介绍

这是内部培训文档,这篇文章就是用于对未接触过maven的人进行简单的介绍

maven的用途

maven是一个很好用的项目管理和构建的工具,主要有三大方面的功能。
1. 描述项目信息。例如名字、开发团队名录、网站什么什么的
2. 依赖库管理。这个功能太重要了,实际上这就是我们用maven的主要原因之一
3. 自动化的构建。maven可以将项目过程规范化、自动化、高效化以及强大的可扩展性,利用maven自身及其插件还可以获得代码检查报告、单元测试覆盖率、实现持续集成等等。

pom.xml

每一个maven的项目均有一个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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.linzi.commoms</groupId>
    <artifactId>common-utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>名字</name>
    <description>说明</description>

    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <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>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

这个例子就描述了maven的基础构建,如果想了解详细的结构,可直接查看xsd文件(http://maven.apache.org/xsd/maven-4.0.0.xsd) 。

  • 第一部分:项目信息
    文件上部分都是都是项目信息,名字、说明、版本自然就是顾名思义了,特别要说明就是 groupIdartifactId ,这可理解为项目的分类id和项目自己的id,这两个id加起来就是该项目的唯一id,这个唯一id可方便在依赖库中定位这个项目。groupId + artifactId + 版本,就可以定位一个jar文件。
    项目信息中还有其他杂七杂八的信息,xsd文件中有详细的描述,这里就不多说了,只有例子中的5项是必填项。常用的信息项有:

    • modelVersion: 所使用的object model版本,一般不需要修改
    • groupId: 是项目创建团体或组织的唯一标志符,通常是域名倒写,如groupId org.apache.maven.plugins 就是为所有 maven 插件预留的
    • artifactId:是项目artifact唯一的基地址名
    • packaging: artifact打包的方式,如jar、war、ear等等。默认为jar。这个不仅表示项目最终产生何种后缀的文件,也表示build过程使用什么样的lifecycle。
    • version: artifact的版本,通常能看见为类似0.0.1-SNAPSHOT,其中SNAPSHOT表示项目开发中,为开发版本
    • name: 表示项目的展现名,在maven生成的文档中使用
    • url:表示项目的地址,在maven生成的文档中使用
  • 第二部分:dependencies 依赖库
    这是我们最看着的功能之一。我们传统的项目中有很多的jar包,这些jar包都要上传到svn或者git,这实在太麻烦了,特别是jar包更新的时候,我们都要删除原来的jar包,重新上次,而且当我们引入spring之类的包时,因为spring自身需要很多依赖包,所以我们还有去找这些依赖包。maven的好处就是我们只需要在这里说明我们需要什么包,maven会自动将这些包以及这些包下载到本地,并加入到我们eclipse项目的classpath中。本地路径通常就是%USER%/.m2/repository。这个路径可以在maven安装目录下conf目录的settings.xml中修改,或者在用户目录下的.m2目录下的settings.xml中修改。

  • 第三部分:构建
    maven最吸引人的地方之一就是强大的构建功能。maven的常用命令行可理解为:

mvn 截止的阶段名字1 [截止的阶段名字2] [截止的阶段名字3]
#例如
mvn clean install site
maven和ant的命令行有很大区别,虽然都是"mvn或者ant 一个名字" 这个形式,但ant的名字是一个任务的名字,mavan执行时可以不是仅仅执行一个任务,而是执行一个序列的任务,mvn后面的跟名字是指**执行完哪个任务就退出* ***,而不是仅仅执行一个任务就完事。好了,这有个问题,我们怎么知道mvn执行的任务序列是什么东西?这个“任务序列”专业的名称叫**Lifecycle(生命周期)**,而里面的“任务”叫**phase**。

Repositories

Repositories是存储所有的依赖包的,我们在项目中需要使用某种工具时,在pom中声明dependency,编译代码时就会根据dependency去下载工具(Artifact),供自己使用。

  • 本地仓库
    对于自己的项目完成后可以通过mvn install命令将项目放到本地仓库(Repositories)中,本地仓库是指本机存储Artifact的仓库,对于windows机器本地仓库地址为系统用户的.m2/repository下面。

    • 远程仓库
      如果希望发布的工具包可被他人使用,我们就需要将工具包发布到外网。俺老人家的远程仓库的地址是 (http://maven.liangwj.com) ,在上面有账号的同学可将工具包发布到这个的远程仓库,账号可找我开通。需要在settings.xml中设置好该地址才能使用公司仓库中的内容。
    • maven中心仓库
      maven有为全世界提供依赖库下载的中心仓库 http://mvnrepository.com ,我们需要的各类依赖包均可以在这些获取,在不做任何设置的情况下,maven默认的仓库地址就是他们自家的仓库。
    • 国内镜像
      对于我们来说,maven的仓库是在海外的,下载速度超级慢。所以,我们一般会修改一下settings.xml文件,设置一下使用国内镜像。我们一般是使用阿里云的镜像。

生命周期 (其实下来的部分不用看了...)

生命周期是maven的重要特征,官方文档见 Introduction to the Build Lifecycle, maven内置了3套 生命周期:DEFAULT, CLEAN和SITE:

  • DEFAULT: 集成了编译、测试、打包等各类任务。根据打包的文件不同,maven提供了不同的默认生命周期,例如打包成ear就比打包成war所执行的phase要少,完整的任务列表非常的长,官方文档参加Lifecycle Reference, 下面挑重点的说:
    • validate - 验证项目是否正确以及必须的信息是否可用,包括依赖库什么的
    • compile - 就是编译 (内置插件)
    • test - 运行test源码目录中的测试用例 (内置插件)
    • package - 根据项目信息中package的定义打包编译后的代码,在target目录下生成package文件 (内置插件)
    • integration-test - 将打包后的文件部署到测试环境中,并检查是部署正常,需要插件支持
    • verify - 验证打包后的文件是否正常
    • install - 安装package到本地仓库,方便本地其它项目使用 (内置插件)
    • deploy - 拷贝最终的package到远程仓库和替他开发这或项目共享.
  • CLEAN: 顾名思义,就是清理了。phase包括:
    • pre-clean - 清理之前
    • clean - 清理 (内置插件)
    • post-clean - 清理之后
  • SITE:就是根据项目信息生成一堆的html文件,用于上传到网站上。
    • pre-site - 生成文件之前
    • site - 生成文件 (内置插件)
    • post-site - 生成文件之后
    • site-deploy - 将生成的文件部署到web server

build

maven实际是可灵活个执行各类插件的框架,mvn命令其实就是运行了一堆的插件,我们主要关注的是构建阶段的插件。在构建过程中,生命周期中的执行的每一个phase其实就是运行一个插件程序,maven很贴心的提供了一大堆的内置插件,可满足我们绝大多数情况下的要求,常用的插件可见官网 Available Plugins,有点时候,我们可能会调整一下里面的参数,例如:

  • 例子
    我们想在test阶段时,我们在各类的代码,但例如这些MyServuceTest.java以Test.java的才是TestCase,所以我们可以为test的内置插件设置一下参数,要求只看Testa结尾的.java文件,我们可以这样设置
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.17</version>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 多源码目录
    很多时候我们不乐意所有源码的放在一个目录里面,因为我们有的源码是自动生成出来的,例如Hibernate Tools生成的代码,eclipse中右键点击一个xsd文件时,生成的用于解析这个xsd文件的java代码,这些自动生成出来的代码,我们一般不会和我们手写出来的代码放在同一个目录。
    <build>
        <plugins>
            <!-- 扩展源代码和资源文件目录 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.9</version>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <!-- 我们可以通过在这里添加多个source节点,来添加任意多个源文件夹 -->
                                <source>src/main/alipay</source>
                                <source>src/main/genCode</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  • 打包源码中非java的文件
    正常情况下,我们会将xml等文件放到resource目录下,maven打包时,会将这些文件打到包中,但某些时候,我们还是要将xml等文件放到src/main/java之类的目录下,而maven默认是不会将这些文件打包的,这个时候,我们就需要配置一下
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <!-- 是否替换资源中的属性 -->
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>

        <testResources>
            <testResource>
                <directory>src/test/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <!-- 是否替换资源中的属性 -->
                <filtering>false</filtering>
            </testResource>
        </testResources>
    </build>
  • 将内容发布到第三方仓库
    我们用mvn deploy命令就可以将项目自动打包,并自动发布,我们需要配置一下发布的地址
    <distributionManagement>
        <repository>
            <id>LinziRepo</id>
            <name>LinZi Repository Release</name>
            <url>http://maven.liangwj.com/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>LinziRepo</id>
            <name>LinZi Repository Snapshots</name>
            <url>http://maven.liangwj.com/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

注意,发布是需要有权限的,maven会自动根据repo的id在settings.xml文件中找这台服务器的用户名和密码。

maven常用参数和命令

主要介绍maven常用参数和命令以及简单故障排除

  1. mvn常用参数
    • mvn -e 显示详细错误
    • mvn -U 强制更新snapshot类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖)
    • mvn -o 运行offline模式,不联网更新依赖
    • mvn -N仅在当前项目模块执行命令,关闭reactor
    • mvn -pl module_name在指定模块上执行命令
    • mvn -ff 在递归执行命令过程中,一旦发生错误就直接退出
    • mvn -Dxxx=yyy指定java全局属性
    • mvn -Pxxx引用profile xxx
  2. 首先是 Build Lifecycle中介绍的命令
    • mvn test-compile 编译测试代码
    • mvn test 运行程序中的单元测试
    • mvn compile 编译项目
    • mvn package 打包,此时target目录下会出现maven-quickstart-1.0-SNAPSHOT.jar文件,即为打包后文件
    • mvn install 打包并安装到本地仓库,此时本机仓库会新增maven-quickstart-1.0-SNAPSHOT.jar文件。

    每个phase都可以作为goal,也可以联合,如之前介绍的mvn clean install

  3. maven 日用三板斧

    • mvn archetype:generate 创建maven项目
    • mvn package 打包,上面已经介绍过了
    • mvn package -Prelease打包,并生成部署用的包,比如deploy/*.tgz
    • mvn install 打包并安装到本地库
    • mvn eclipse:eclipse 生成eclipse项目文件
    • mvn eclipse:clean 清除eclipse项目文件
    • mvn site 生成项目相关信息的网站
  4. maven插件常用参数
    • mvn -Dwtpversion=2.0 指定maven版本
    • mvn -Dmaven.test.skip=true 如果命令包含了test phase,则忽略单元测试
    • mvn -DuserProp=filePath 指定用户自定义配置文件位置
    • mvn -DdownloadSources=true -Declipse.addVersionToProjectName=true eclipse:eclipse 生成eclipse项目文件,尝试从仓库下载源代码,并且生成的项目包含模块版本(注意如果使用公用POM,上述的开关缺省已打开)
  5. maven简单故障排除
    • mvn -Dsurefire.useFile=false如果执行单元测试出错,用该命令可以在console输出失败的单元测试及相关信息
    • set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=256m 调大jvm内存和持久代,maven/jvm out of memory error
    • mvn -X maven log level设定为debug在运行
    • mvndebug 运行jpda允许remote debug
    • mvn –help 这个就不说了。。
Sidebar