Maven入门指南(二)
转载自并发编程网 – ifeve.com本文链接地址: Maven入门指南(二)
Maven目录结构
Maven有一个标准的目录结构。
如果你在项目中遵循Maven的目录结构,就无需在pom文件中指定源代码、测试代码等目录。
Maven的目录结构布局,参考Maven标准目录结构介绍
以下为最重要的目录:
- src - main - java - resources - webapp - test - java - resources - target
src目录是源代码和测试代码的根目录。main目录是应用的源代码目录。test目录是测试代码的目录。main和test下的java目录,分别表示应用的java源代码和测试代码。
resources目录包含项目的资源文件,比如应用的国际化配置的属性文件等。
如果是一个web项目,则webapp目录为web项目的根目录,其中包含如WEB-INF等子目录。
target目录是由Maven创建的,其中包含编译后的类文件、jar文件等。当执行maven的clean
目标后,target目录会被清空。
如果项目中没有遵循Maven项目结构,可以在pom文件中如下配置
<build> <!--默认源代码目录--> <sourceDirectory>src/main/java </sourceDirectory> <!--默认测试源代码目录--> <testSourceDirectory>src/test/java</testSourceDirectory> <!--默认资源目录--> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <!--默认测试资源目录--> <testResources> <testResource> <directory>src/test/resources</directory> </testResource> </testResources> </build>
但<sourceDirectory>只能指定一个源代码目录,不能指定多个。
可以使用插件build-helper-maven-plugin。指定多个源代码目录、多个资源目录。用法如下:
< plugins > < !-- 指定多个源代码目录、多个资源文件目录 --> <plugin > <groupId > org.codehaus.mojo < /groupId> <artifactId>build-helper-maven-plugin</artifactId > <version > 1.8 < /version> <executions> <execution> <id>add-source</id > < phase > generate - sources < /phase> <goals> <goal>add-source</goal > < /goals> <configuration> <sources> <source>src/java / main < /source> <source>src/java / generated < /source> </sources > < /configuration> </execution > < /executions> </plugin > < /plugins>
项目依赖
除非你的项目很小,否则会需要外部的Java API或者框架以jar包形式提供的依赖。当你编译项目代码的时候,需要classpath上的这些jar包。
使项目依赖的外部jar包以正确的版本保持最新状态,是一项艰巨的任务。而且,这些外部的jar包还会依赖其它的外部jar包。递归地下载所有这些外部依赖(jar包),并且要确保下载的版本都是正确的,是非常麻烦的。尤其是当项目变得越来越大,外部依赖越来越多的时候。
幸运的是,Maven内嵌有依赖管理的功能。你只需要在pom文件里指定依赖jar包的名称、版本号,Maven会自动下载并放到你的Maven本地仓库中。如果这些外部jar包依赖了其它的库,它们也会被下载到你的Maven本地仓库。
在pom文件的dependencies
属性中指定项目依赖,如:
<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.jenkov.crawler</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> </build> </project>
在dependencies
属性下有两个dependency
子属性,每一个dependency
属性描述了一个外部依赖。
每一个依赖由groupId, artifactId和version来描述。如果你有印象,这和我们在pom文件的开头用来标识项目的方式是一样的。上面的示例表明,项目的依赖为 org.jsoup组织下的1.7.1版本的jsoup,以及junit组织下的4.8.1版本的junit。
当Maven执行该pom文件时,将从Maven的中央仓库里下载这两个jar包并放到Maven的本地仓库。如果本地仓库中已经有了这两个依赖,Maven就不会去下载了。只有本地仓库中没有的依赖才会被下载。
有的时候,指定的依赖在Maven的中央仓库里没有。你可以直接下载这些依赖,然后放到Maven的本地仓库。这些依赖必须放到与groupId、 artifactId和version匹配的子目录中。用/替换所有的点(.)并且使用/分隔groupId、artifactId和version,这 就是与该依赖匹配的子目录。
上面示例中的两个依赖将会被放到以下子目录中:
MAVEN_REPOSITORY_ROOT/junit/junit/4.8.1 MAVEN_REPOSITORY_ROOT/org/jsoup/jsoup/1.7.1
外部依赖
Maven的外部依赖指的是不在Maven的仓库(包括本地仓库、中央仓库和远程仓库)中的依赖(jar包)。它可能位于你本地硬盘的某个地方,比如web应用的lib目录下。这里的“外部”是对Maven仓库系统而言的,不仅仅是对项目而言的。大部分的外部依赖都是针对项目的,很少的外部依赖是针对仓库系统的(即不在仓库中)。
配置外部依赖的示例如下:
<dependency> <groupId>mydependency</groupId> <artifactId>mydependency</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${basedir}\war\WEB-INF\lib\mydependency.jar</systemPath> </dependency>
groupId和artifactId为依赖的名称,即API的名称。scope属性为system。systemPath属性为jar文件的路径。${basedir}为pom文件所在的目录,路径中的其它部分是相对于该目录而言的。
快照依赖
快照依赖指的是那些还在开发中的依赖(jar包)。与其经常地更新版本号来获取最新版本,不如你直接依赖项目的快照版本。快照版本的每一个build版本都会被下载到本地仓库,即使该快照版本已经在本地仓库了。总是下载快照依赖可以确保本地仓库中的每一个build版本都是最新的。
在pom文件的最开头(设置groupId和artifactId的地方),在版本号后追加-SNAPSHOT,则告诉Maven你的项目是一个快照版本。如:
<version>1.0-SNAPSHOT</version>
可以看到加到版本号后的-SNAPSHOT。
在配置依赖时,在版本号后追加-SNAPSHOT表明依赖的是一个快照版本。如:
<dependency> <groupId>com.jenkov</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
追加在version后的-SNAPSHOT告诉Maven这是一个快照版本。
可以在Maven配置文件中设置快照版本下载的频率。
Maven仓库
Maven仓库就是存储jar包和一些元数据信息的目录。其中的元数据即pom文件,描述了该jar包属于哪个项目,以及jar包所需的外部依赖。该元数据信息使得Maven可以递归地下载所有的依赖,直到整个依赖树都下载完毕并放到你的本地仓库中。
Maven仓库的详细介绍参考Maven 仓库介绍,快速介绍如下:
Maven有三种类型的仓库:
- 本地仓库
- 中央仓库
- 远程仓库
Maven根据以上的顺序去仓库中搜索依赖。首先是本地仓库,然后是中央仓库,最后,如果pom文件中配置了远程仓库,则会去远程仓库中查找。
下图说明了三种仓库的类型以及位置:
本地仓库
本地仓库就是开发者电脑上的一个目录。该仓库包含了Maven下载的所有依赖。一般来讲,一个本地仓库为多个不同的项目服务。因此,Maven只需下载一次,即使有多个项目都依赖它(如junit)。
通过mvn install
命令可以将你自己的项目构建并安装到本地仓库中。这样,你的其它项目就可以通过在pom文件将该jar包作为外部依赖来使用。
Maven的本地仓库默认在你本机的用户目录下。不过,你可以在Maven的配置文件中修改本地仓库的路径。Maven的配置文件也在用户目录下(user-home/.m2),文件名为settings.xml。以下示例为本地仓库指定其它的路径:
<settings> <localRepository> d:\data\java\products\maven\repository </localRepository> </settings>
中央仓库
Maven的中央仓库由Maven社区提供。默认情况下,所有不在本地仓库中的依赖都会去这个中央仓库查找。然后Maven会将这些依赖下载到你的本地仓库。访问中央仓库不需要做额外的配置。
远程仓库
远程仓库是位于web服务器上的一个仓库,Maven可以从该仓库下载依赖,就像从中央仓库下载依赖一样。远程仓库可以位于Internet上的任何地方,也可以是位于本地网络中。
远程仓库一般用于放置组织内部的项目,该项目由多个项目共享。比如,由多个内部项目共用的安全项目。该安全项目不能被外部访问,因此不能放在公开的中央仓库下,而应该放到内部的远程仓库中。
远程仓库中的依赖也会被Maven下载到本地仓库中。
可以在pom文件里配置远程仓库。将以下的xml片段放到属性之后:
<repositories> <repository> <id>jenkov.code</id> <url>http://maven.jenkov.com/maven2/lib</url> </repository> </repositories>
Maven的构建生命周期、阶段和目标
当使用Maven构建项目时,会遵循一个构建生命周期。该生命周期分为多个构建阶段,而构建阶段又分为多个构建目标。Maven的构建周期、构建阶段和目标的更多细节请参考Maven构建周期介绍,这里是一个快速介绍。
构建生命周期
Maven有三个内嵌的构建生命周期:
- default
- clean
- site
每一个构建生命期关注项目构建的不同方面。因此,它们是独立地执行的。Maven可以执行多个生命期,但是它们是串行执行的,相互独立,就像你执行了多条独立的Maven命令。
default
生命期关注的是项目的编译和打包。clean
生命期关注的是从输出目录中删掉临时文件,包括自动生成的源文件、编译后的类文件,之前版本的jar文件等。site
生命期关注的是为项目生成文档。实际上,site
可以使用文档为项目生成一个完整的网站。
构建阶段
每一个构建生命期被分为一系列的构建阶段,构建阶段又被分为构建目标。因此,整个构建过程由一系列的构建生命期、构建阶段和构建目标组成。
你可以执行一个构建生命期,如clean
或site
,一个构建阶段,如default
生命期的install
,或者一个构建目标,如dependency:copy-dependencies
。注意:你不能直接执行default
生命期,你需要指定default
生命期中的一个构建阶段或者构建目标。
当你执行一个构建阶段时,所有在该构建阶段之前的构建阶段(根据标准构建顺序)都会被执行。因此,执行install
阶段,意味着所有位于install
阶段前的构建阶段都会被执行,然后才执行install
阶段。
default
生命期更多的关注于构建代码。由于你不能直接执行default
生命期,你需要执行其中一个构建阶段或者构建目标。default
生命期包含了相当多的构建阶段和目标,这里不会所有都介绍。最常用的构建阶段有:
构建阶段 描述 validate 验证项目的正确性,以及所有必需的信息都是否都存在。同时也会确认项目的依赖是否都下载完毕。 compile 编译项目的源代码 test 选择合适的单元测试框架,对编译后的源码执行测试;这些测试不需要代码被打包或者部署。 package 将编译后的代码以可分配的形式打包,如Jar包。 install 将项目打包后安装到本地仓库,可以作为其它项目的本地依赖。 deploy 将最终的包复制到远程仓库,与其它开发者和项目共享。
将构建阶段的名称作为参数传给mvn
命令,就是执行该构建阶段,如:
mvn package
该示例执行package
构建阶段,因此在Maven的构建阶段序列中所有位于该阶段之前的阶段也都会被执行。
如果标准的Maven构建阶段和目标无法满足项目的需要,可以创建Maven插件增加你需要的构建功能。
构建目标
构建目标是Maven构建过程中最细化的步骤。一个目标可以与一个或多个构建阶段绑定,也可以不绑定。如果一个目标没有与任何构建阶段绑定,你只能将该目标的名称作为参数传递给mvn
命令来执行它。如果一个目标绑定到多个构建阶段,该目标在绑定的构建阶段执行的同时被执行。
Maven构建配置
Maven构建配置使你能使用不同的配置来构建项目。不用创建两个独立的pom文件。你只需使用不同的构建配置指定不同的配置文件,然后使用该配置文件构建项目即可。
关于构建配置的详细信息可以参考Maven POM参考的Profile部分。这里是一个快速的介绍。
Maven的构建配置在pom文件的profiles
属性中指定,例如:
<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.jenkov.crawler</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0.0</version> <profiles> <profile> <id>test</id> <activation>...</activation> <build>...</build> <modules>...</modules> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <dependencies>...</dependencies> <reporting>...</reporting> <dependencyManagement>...</dependencyManagement> <distributionManagement>...</distributionManagement> </profile> </profiles> </project>
构建配置描述的是当使用该配置构建项目时,对pom文件所做的修改,比如修改应用使用的配置文件等。profile
属性中的值将会覆盖其上层的、位于pom文件中的配置。
在profile
属性中,有一个activation
子属性。该属性指定了启用该构建配置的条件。选择构建配置的一种方式是在settings.xml
文件中指定;另一种方式是在Maven命令行使用-P profile-name
指定。更多细节参考构建配置的文档。
Maven插件
使用Maven插件,可以向构建过程添加自定义的动作。创建一个简单的Java类,该类继承一个特殊的Maven类,然后为项目创建一个pom文件。该插件应该位于其项目下。
为了使本教程简短,关于开发插件的更多细节请参考Maven插件开发中心
未来拿不出手,过去会有谁听。
作者:aLong
出处:http://www.cnblogs.com/keerdi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。