一. Maven的目录结构:
bin
boot
conf
lib
LICENSE.txt
NOTICE.txt
README.txt
Bin: 该目录包含了mvn运行的脚本,这些脚本用来配置Java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。其中mvn是基于UNIX平台的shell脚本,mvn.bat是基于Windows平台的bat脚本。在命令行输入任何一条mvn命令时,实际上就是在调用这些脚本。该目录还包含了mvnDebug和mvnDebug.bat两个文件,同样,前者是UNIX平台的shell脚本,后者是windows的bat脚本。那么mvn和mvnDebug有什么区别和关系呢?打开文件我们就可以看到,两者基本是一样的,只是mvnDebug多了一条MAVEN_DEBUG_OPTS配置,作用就是在运行Maven时开启debug,以便调试Maven本身。此外,该目录还包含m2.conf文件,这是classworlds的配置文件,稍微会介绍classworlds。
Boot: 该目录只包含一个文件,以maven 3.0为例,该文件为plexus-classworlds-2.2.3.jar。plexus-classworlds是一个类加载器框架,相对于默认的java类加载器,它提供了更丰富的语法以方便配置,Maven使用该框架加载自己的类库。更多关于classworlds的信息请参考http://classworlds.codehaus.org/。对于一般的Maven用户来说,不必关心该文件。
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等等。(对于Maven 2来说,该目录只包含一个如maven-2.2.1-uber.jar的文件原本各为独立JAR文件的Maven模块和第三方类库都被拆解后重新合并到了这个JAR文件中)。可以说,这个lib目录就是真正的Maven。关于该文件,还有一点值得一提的是,用户可以在这个目录中找到Maven内置的超级POM,这一点在8.5小节详细解释。其他: LICENSE.txt记录了Maven使用的软件许可证Apache License Version 2.0; NOTICE.txt记录了Maven包含的第三方软件;而README.txt则包含了Maven的简要介绍,包括安装需求及如何安装的简要指令等等。
二. 设置
1. 设置MAVEN_OPTS环境变量。我们通常需要设置MAVEN_OPTS的值为:-Xms128m -Xmx512m,因为Java默认的最大可用内存往往不能够满足Maven运行的需要,比如在项目较大时,使用Maven生成项目站点需要占用大量的内存,如果没有该配置,我们很容易得到java.lang.OutOfMemeoryError。因此,一开始就配置该变量是推荐的做法。
2. 配置用户范围settings.xml。我们推荐使用用户范围的settings.xml,主要原因是为了避免无意识地影响到系统中的其他用户。当然,如果你有切实的需求,需要统一系统中所有用户的settings.xml配置,当然应该使用全局范围的settings.xml。除了影响范围这一因素,配置用户范围settings.xml文件还便于Maven升级。直接修改conf目录下的settings.xml会导致Maven升级不便,每次升级到新版本的Maven,都需要复制settings.xml文件,如果使用~/.m2目录下的settings.xml,就不会影响到Maven安装文件,升级时就不需要触动settings.xml文件。
3. 在IDE中配置Maven插件时使用与命令行一致的Maven。在m2eclipse环境中,点击菜单栏中的Windows,然后选择Preferences,在弹出的对话框中,展开左边的Maven项,选择Installation子项,在右边的面板中,我们能够看到有一个默认的Embedded Maven安装被选中了,点击Add…然后选择我们的Maven安装目录M2_HOME,添加完毕之后选择这一个外部的Maven。
三:pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- project元素是根元素 --> <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模型的版本,对maven2和3来说只能4.0.0 --> <modelVersion>4.0.0</modelVersion> <!-- 下面3个元素定义了一个项目基本的坐标 --> <groupId>com.wb.mvntest</groupId> <!-- groupId定义了项目属于哪个组 --> <artifactId>hello-world</artifactId> <!-- artifactId定义了当前Maven项目在组中唯一的ID,一般是模块名 --> <version>1.0-SNAPSHOT</version> <!-- version指定了项目当前的版本 --> <packaging>jar</packaging> <!-- 打包方式,默认jar --> <name>Maven Hello World Project</name> <!-- 声明一个对于用户更为友好的项目名称,不是必须的 --> <!-- 可以包含多个dependency元素以声明项目的依赖 --> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> <!-- 定义依赖范围,test表示只对测试有效,默认值是compile,表示对主代码和测试代码都有效 --> </dependency> </dependencies> <!-- 没有任何实际的java代码,我们就能够定义一个Maven项目的POM,能让项目对象模型最大程度地与实际代码相独立,做到了解耦 --> </project>
四:main代码
项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中(比如jar),而测试代码只在运行测试时用到,不会被打包。默认情况下,Maven假设项目主代码位于src/main/java目录,我们遵循Maven的约定,创建该目录,然后在该目录下创建文件com/wb/mvntest/helloworld/HelloWorld.java
package com.wb.mvntest.helloworld;
public class HelloWorld {
public String sayHello() {
return "Hello Maven";
}
public static void main(String[] args) {
System.out.print( new HelloWorld().sayHello() );
}
}
代码编写完毕后,使用Maven进行编译,在项目跟目录下运行命令mvn clean compile。clean告诉Maven清理输出目录target/,compile告诉Maven编译项目主代码。
五:test代码
Maven项目中默认的测试代码目录是src/test/java,我们创建该目录,然后在该目录下创建文件com/wb/mvntest/helloworld/HelloWorldTest.java
package com.wb.mvntest.helloworld;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class HelloWorldTest {
@Test
public void testSayHello() {
HelloWorld helloWorld = new HelloWorld();
String result = helloWorld.sayHello();
assertEquals("Hello Maven", result);
}
}
代码编写完毕后,使用Maven执行测试,在项目跟目录下运行命令mvn clean test。clean告诉Maven清理输出目录target/,test告诉Maven执行测试。
六:打包和运行
将项目进行编译、测试之后,下一个重要步骤就是打包(package)。Hello World的POM中没有指定打包类型,使用默认打包类型jar,我们可以简单地执行命令 mvn clean package 进行打包。打包实际上就是jar插件的jar目标将项目主代码打包成一个名为hello-world-1.0-SNAPSHOT.jar的文件,该文件也位于target/输出目录中,它是根据artifact-version.jar规则进行命名的,如有需要,我们还可以使用finalName来自定义该文件的名称。
至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar文件到其他项目的Classpath中从而使用HelloWorld类。但是,如何才能让其他的Maven项目直接引用这个jar呢?我们还需要一个安装的步骤,执行 mvn clean install。安装任务install:install将项目输出的jar安装到了Maven本地仓库中,其他Maven项目就可以使用它了。
至此,已经介绍了Maven最主要的命令:mvn clean compile、mvn clean test、mvn clean package、mvn clean install。执行test之前是会先执行compile的,执行package之前是会先执行test的,而类似地,install之前会执行package。
七:使用Archetype生成项目骨架
mvn archetype:generate