Maven的安装与配置
安装
在unix系统上,可以通过创建一个符号链接,然后在环境变量时引用改符号链接,这样做是为了方便升级。
安装目录分析
M2_HOME
设置MAVEN_HOME环境变量指向maven的按照目录。该目录的结构和内容如下:
bin
boot
lib
LICENSE.txt
NOTICE.txt
README.txt
- bin:该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的java系统属性,然后执行java命令。其中包括mvn、mvnDebug和m2.conf。
- 其中m2.conf是classworlds的配置文件。
- mvnDebug比mvn多了一条MAVEN_DEBUG_OPTS配置。
- boot:该目录只包含一个文件,即
plexus-classworlds-2.6.0.jar
。plexus-classworlds
是类加载框架,相对于默认的java类加载器,它提供更丰富的语法以方便配置,maven使用该框架加载自己的类库。更多关于classworlds的信息请参考http://classworlds.codehaus.org/【一般不用关心这个文件】 - conf:该目录包含了一个非常重要的文件
settings.xml
。直接修改该文件,就能在机器上全局地定制Maven的行为。一般情况下,我们更偏向于复制该文件至/.m2/目录下(这里表示用户目录),然后修改该文件,在用户范围定制Maven的行为。本书的后面将会多次提到该settings.xml,并逐步分析其中的各个元素。 - lib:该目录包含了所有Maven运行时需要的Java类库,Maven本身是分模块开发的,因此用户能看到诸如mavn-core-3.0.jar、maven-model-3.0.jar之类的文件,此外这里还包含一些Maven用到的第三方依赖如common-cli-1.2.jar、google-collection-1.0.jar等等。可以说,这个lib目录就是真正的Maven。关于该文件,还有一点值得一提的是,用户可以在这个目录中找到Maven内置的超级POM,这一点在8.5小节详细解释。
- 其他:
LICENSE.txt
记录了Maven使用的软件许可证Apache License Version 2.0;NOTICE.txt
记录了Maven包含的第三方软件;而README.txt
则包含了Maven的简要介绍,包括安装需求及如何安装的简要指令等等。
~/.m2
~
代表用户目录,Windows下的C:/Users/xxx
和linux下的~
目录。
运行命令:
mvn help:system
这个命令会打印出所有的java系统属性和环境变量。而上面这个命令会下载maven-help-plugin
这个插件到本地仓库。
在用户目录下,可以发现.m2
文件夹。默认情况下,该文件夹下放置了maven本地仓库.m2/repository
。所有maven构件(artifact)都被存储到该仓库中,以方便重用。可以到~/.m2/repository/org/maven/plugin/maven-help-plugins/
目录下找到刚才下载的maven-help-plugin
的pom文件和jar文件。
由于maven仓库是通过简单文件系统透明地展示给maven用户的,有些时候可以绕过maven直接查询或修改仓库文件。
设置http代理
有时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问Internet。这种情况就要为maven配置http代理,才能让你正常访问外部仓库,以下载所需要的资源。
首先确认自己无法直接访问公共的maven*仓库,直接运行命令ping repol.maven.org
。如果需要代理,先检查代理是否通畅:telnet 代理IP
。
检查完毕后,则编辑~/.m2/setting.xml
文件,添加代理:
<proxies>
<proxy>
<id>my-proxy</id>
<active>true</active>
<protocol>http</protocol>
<http>xxx</http>
<port>xxx</port>
<!--
<username>xxx</username>
<password>xxx</password>
<nonProxyHosts>repository.mycom.com|*.google.com</nonProxyHosts>
-->
</proxy>
</proxies>
proxies
下有多个proxy
元素,如果声明了多个,则默认情况下第一个被激活的proxy会生效。这里声明了一个id为my-proxy
的代理,active的值为true表示激活该代理,protocol
表示代理协议然后指定主机名和端口。当代理服务需要认证的时候,就需要配置username
,password
。nonProxyHost
用来指定哪些主机名不需要代理,可以使用|
分好分割多个主机名。此外,该配置也支持通配符,如*.google.com
表示所有以google.com
结尾的域名访问都不需要通过代理。
Maven入门使用
编写POM
就像Make的Makefile、Ant的build.xml一样,Maven项目的核心是pom.xml。POM(project object model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
<?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>com.ssozh</groupId>
<artifactId>Mirana</artifactId>
<version>1.0-SNAPSHOT</version>
<name>presbyter of moon(pom)</name>
</project>
第一个xml头定义了xml版本,第二行是xsd,根元素下的第一个子元素modelVersion
指定了当前POM模型的版本,固定是4.0.0
而groupId
、artifactId
和version
三个元素定义了一个项目基本的坐标,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。
- groupId:定义了项目属于哪个组。
- artifactId:定于了当前maven项目在组中的唯一的ID。
- version:指定了项目的当前版本。
- name:可以给项目起名。但是不是必须的
编写主代码
项目的主代码和测试代码不同,项目的主代码会被打包到最终的构建中(如jar),而测试代码只会在运行测试时用到,不会被打包。
默认情况下,maven假设项目主代码位于src/main/java
目录中。并且你写的java类的包名一定要与之前在POM中定义的groupId和artifactId吻合。
以上面为例,这个java类包名一定要是:com.ssozh
代码编写完毕以后,在根目录运行命令:
mvn clean compile
clean告诉maven清理输出目录target/,compile告诉maven编译项目主代码,从输出中看到Maven首先执行了clean:clean
任务,删除target/
目录。默认情况下,Maven构建的所有输出都在target/
目录;接着执行resouces:resources任务(未定义项目资源,暂且略过);最后执行compiler:compile
任务,将项目主代码编译至target/classes
目录。
clean:clean
和剩下的两个对应了一些Maven插件及插件目标,后文会详解Maven插件及其编写方法。
编写测试代码
为项目添加Junit依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
上面多了个scope
标签,为依赖范围,若依赖范围为test则表示该依赖只对测试有效。换句话说,测试代码中import JUnit
代码没有问题,但是如果在主代码中import
就会造成编译错误。
如果不声明依赖范围,那么默认值就是compile
,表示该依赖对主代码和测试代码都有效。
然后在测试环境中写代码:
package com.ssozh;
import com.ssozh.learn.Helloworld;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ApplicationTestBase {
@Test
public void test_sayHello(){
Helloworld helloworld = new Helloworld();
String s = helloworld.seeHello();
assertEquals("Hello world!", s);
}
}
一个典型的单元测试包括:
- 准备测试类及数据
- 执行要测试的行为
- 检查结果
在JUnit 3中约定你所有需要执行测试的方法都以test开头,JUnit4则需要增加一个@Test注解。测试用例编写完毕,就可以调用maven执行测试。
mvn clean test
以上这段代码执行了这些插件:
clean、resources、compiler、resources、compiler、surefire:test
surefile:test任务运行测试, surefile是Maven中负责执行测试的插件,这里他运行测试用例,并且输出测试报告。
打包和运行
将项目进行编译、测试之后,下一个重要步骤就是打包。POM中没指定打包类型,默认使用jar。简单地执行:
mvn clean package
这个地方jar插件会将主代码打包成一个XXX-SNAP-SHOT.jar
的文件,并输出在target/
输出目录中。
至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar文件到项目的classpath中,从而可以使用类。如果想让其他的maven项目直接引用这个jar,还需要一个安装步骤:
mvn clean install
从出输出可以看到该任务将项目输出的jar安装到了maven本地仓库中,打开相应的文件夹看到这个项目的pom和jar。
我们已经体验了maven最主要的命令。但是默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不回添加到manifest中(打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。为了生产可执行的jar文件,需要借助maven-shade-plugin,配置该插件如下:
略
总结
命令 | 说明 |
---|---|
mvn clean compile | 编译,将打码打包到target/classes里面 |
mvn clean test | 测试,测试测试代码 |
mvn clean package | 打包,打包到classpath下面,打包之前会执行编译和测试 |
mvn clean install | 安装到本地maven库,上面3步骤都要执行 |
mvn clean deploy | 部署到远程库 |
注释:
maven项目分为src目录,resource目录,test/src目录,test/resource目录:
其中src和resource对应到项目的target\classes目录,如果在src目录调用classpath,则class的根目录为target\classes
test/src,test/resource对应到test-classes目录,如果在test/src目录调用classpath,则class的根目录为target\test-classes
使用archetype生成项目骨架
maven提供了archetype以帮助我们快速勾勒出项目骨架。命令:
mvn archetype:generate
也可以从IDEA 生成: