Maven入门

Published: by Creative Commons Licence

Maven的介绍和安装配置

Maven是一个跨平台的项目管理工具;Maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。(Apache组织的开源项目)

构建(Build):编译、运行单元测试、生成文档、打包和部署等工作。

Make和Ant是过程式的,开发者需要显示指定每一个目标,以及完成该目标所需要执行的任务。 Maven是声明式的,项目构建过程和各个阶段所需的工作都由插件实现,并且大部分插件都是现成的,开发者只需要声明项目的基本元素,Maven就执行内置的、完整的构建过程。

Ubuntu 16安装Maven: sudo apt install maven 查看Maven信息,运行: mvn -v

Maven 使用惯例优于配置的原则 。它要求在没有定制之前,所有的项目都有如下的结构:

目录 目的
${basedir} 存放 pom.xml和所有的子目录
${basedir}/src/main/java 项目的 java源代码
${basedir}/src/main/resources 项目的资源,比如说 property文件
${basedir}/src/test/java 项目的测试类,比如说 JUnit代码
${basedir}/src/test/resources 测试使用的资源

另外: 编译后 的 classes 会放在 ${basedir}/target/classes 下面, JAR 文件会放在 ${basedir}/target 下面。

本地仓库

运行mvn help:system命令,这条命令的目的是让Maven执行一个真正的任务,它会下载相关文件(下载maven-help-plugin),这些文件被下载到了Maven本地仓库中。~/.m2文件夹中放置了Maven本地仓库,所有的Maven构件都被放到该仓库中,以方便重用。 可到~/.m2/repository/org/apache/maven/plugins/maven-help-plugins/下找到maven-help-plugin的pom文件和jar文件。

设置HTTP代理

先检测代理服务器地址(218…)和相关端口(3128)是否畅通: telnet 218… 3128 。如果连接正确,输入ctrl + ] 然后 q ,回车退出。

复制Maven home: /usr/share/maven /conf/settings.xml文件到~/.m2/settings.xml 编辑<proxies>下的<proxy>标签即可;默认第一个被激活的proxy会生效。其中active的值为true表示激活该代理,用户和密码等可以注释掉;其中nonProxyHost元素用来指定哪些主机名不需要代理,使用 |分隔多个主机名并支持通配符。

m2eclips

新版Eclipse已经默认安装该插件,插件名称为 Maven Integration for Eclipse WTP (a.k.a m2e-wtp) 简称 m2e。

在Eclipse中创建Maven项目; File – New – Other – Maven

Maven安装最佳实践

设置MAVEN_OPTS环境变量: 运行mvn命令实际上是执行java命令,那么运行Java命令可用的参数也可应用在mvn命令上,可以利用MAVEN_OPTS来做到这一点。 通常设置MAVEN_OPTS的值为 -Xms128m -xmx512m因为Java默认的最大可用内存往往不能满足Maven运行的需要,在项目较大时如果没有此配置,很容易得到java.lang.OutOfMemeoryError。

配置用户范围settings.xml: 全局范围:Maven home: /usr/share/maven /conf/settings.xml文件 用户范围:~/.m2/settings.xml

不要使用IDE内嵌的Maven: 因为内嵌的Maven版本较新,会有各种问题。 在Eclipse中的更改方法:Windows – Preferences – Maven – Installation, Add – 输入Maven Home目录,并取消内嵌Maven。

Maven使用入门

编写POM

POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。

为Hello World项目编辑一个最简单的pom.xml,先创建一个名为 hello-world的文件夹,再新建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">
        <!-- 指定POM模型的版本,Maven 3 是 4.0.0 -->
        <modelVersion>4.0.0</modelVersion>
        <!-- 指定项目属于哪个组。比如在googlecode上建立了一个myapp项目,那么它就是 com.googlecode.myapp  -->
        <groupId>com.juvenxu.mvnbook</groupId>
        <!-- 当前Maven项目在组中的唯一ID -->
        <artifactId>hello-world</artifactId>
        <!-- SNAPSHOT意为快照,说明该项目还在开发中,不稳定 -->
        <version>1.0-SNAPSHOT</version>
        <!-- 声明一个对用户更为友好的项目名称(可选) -->
        <name>Maven Hello World Project</name>
        <!--  以下依赖在 <编写测试代码> 章节处才添加 -->
        <dependencies>
            <!-- 声明项目的依赖 -->
            <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.10</version>
                    <!-- 依赖仍然包含上面的三个最基本的坐标,有了它们Maven就可以自动从中央仓库下载junit-4.10.jar -->
                    
                    <!-- 指定依赖范围为test,表示该依赖只对测试有效 -->
                    <scope>test</scope>
            </dependency>
    </dependencies>
        
</project>

groupId、artifactId、version这三个元素定义了这个项目基本的坐标;在Maven的世界,任何jar、pom、war都是以基于这些基本的坐标进行区分的。

编写主代码

项目的主代码会被打包到最终的构件中(如jar)。默认情况,Maven假设项目主代码位于 src/main/java目录,创建该目录然后在该目录下创建文件 com/juvenxu/mvnbook/helloworld/HelloWorld.java,Java类的包名是com.juvenxu.mvnbook.helloworld这与之前在POM中定义的groupId和artifactId相符合。一般来说,项目中的Java类的包都应该基于项目的groupId和artifactId。

编写一个输出 "Hello World"的程序。

[fan 22:00:49]~/workspace/test/maven/hello-world$ mvn clean compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Hello World Project 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world ---               # clean清除输出目录 target/
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/fan/workspace/test/maven/hello-world/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.2:compile (default-compile) @ hello-world ---            # 编译项目主代码至target/classes目录
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /home/fan/workspace/test/maven/hello-world/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.901 s
[INFO] Finished at: 2017-03-05T22:01:06+08:00
[INFO] Final Memory: 14M/195M
[INFO] ------------------------------------------------------------------------
[fan 22:01:06]~/workspace/test/maven/hello-world$ ls        # 多了个target目录
pom.xml  src/  target/                  

编写测试代码

为了使项目结构保持清晰,主代码与测试代码应该分别位于独立的目录中。 Maven项目中默认的测试代码目录是 src/test/java

JUnit是事实上的单元测试标准。要使用JUnit,首先需要为Hello World项目添加一个JUnit依赖;更改项目的POM:

最终修改的POM见"编写POM"章节的示例。

测试用例编写完毕后,运行 mvn clean test 执行测试。

打包和运行

默认打包类型为jar。简单的执行命令 mvn clean package 进行打包。

jar插件将项目主代码打包成一个jar文件,该文件也位于 target/ 输出目录下;它是根据 artifact-version.jar规则进行命名的。

如果有需要的话,可以复制这个jar文件到其他项目的Classpath中从而使用HelloWorld类。如何让其他的Maven项目直接引用这个jar? 可以执行: mvn clean install 将项目输出的jar安装到Maven本地仓库中(只有构件被下载到本地仓库后,才能由所有Maven项目使用)。

更改Maven镜像

Maven镜像(更改vim ~/.m2/settings.xml文件):

maven默认的远程库(http://repo1.maven.org/maven2)

  • Maven阿里云中央仓库(国内快):
  <mirrors>
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>
  </mirrors>
  • Maven国外镜像
<mirror>    
      <id>ibiblio</id>    
      <mirrorOf>central</mirrorOf>    
      <name>Human Readable Name for this Mirror.</name>    
     <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>    
</mirror>  
<mirror> 
      <id>repo2</id>    
      <mirrorOf>central</mirrorOf>    
      <name>Human Readable Name for this Mirror.</name>    
      <url>http://repo2.maven.org/maven2/</url>    
</mirror>    
<mirror>    
      <id>ui</id>    
      <mirrorOf>central</mirrorOf>    
      <name>Human Readable Name for this Mirror.</name>    
     <url>http://uk.maven.org/maven2/</url>    
</mirror>    
<mirror>    
      <id>jboss-public-repository-group</id>    
      <mirrorOf>central</mirrorOf>    
      <name>JBoss Public Repository Group</name>    
     <url>http://repository.jboss.org/nexus/content/groups/public</url>    
</mirror>  

Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具

本笔记主要参考《Maven实战》

Maven学习

在看完《Maven实战》第3章后再看下面两篇文章。
Apache Maven 入门篇(上)
Apache Maven 入门篇(下)

极客学院: Maven 教程