Maven
来源:互联网 发布:mac osx 更新 编辑:程序博客网 时间:2024/06/05 14:21
1.maven的安装
前提:安装Maven之前要确保已经安装好了jdk,并且配置好了环境变量JAVA_HOME。
1.从apache网上下载maven项目的压缩包。下载地址为:http://maven.apache.org/download.html。比如现在最新的Maven版本是3.0.4,那么我下载好的安装文件就是apache-maven-3.0.4.zip。
2. 将下载后的压缩包解压到Maven的安装目录,比如说是D:\develop,那么解压后就是D:\develop\apache-maven-3.0.4。
3. 添加环境变量M2_HOME,其值为Maven的家目录,如D:\develop\apache-maven-3.0.4。
4.添加环境变量M2(非必须,可直接在path中添加%M2_HOME%\bin;),其值将为maven安装目录的bin目录,即D:\develop\apache-maven-3.0.4\bin,对于windows系统也可以使用%M2_HOME%\bin;,对于linux系统也可以使用$M2_HOME/bin。
5.将环境变量M2加入到PATH变量中,对于windows系统,可以在PATH变量的值后面加上“;%M2%”,对于linux系统,可以使用“export path=
6.还有一个可选的环境变量MAVEN_OPTS,该环境变量主要是配置Maven在使用jdk的时候指定JVM属性的。如指定其值为“-Xms256m -Xmx512m”。
成功:命令窗口使用mvn –version来验证一下Maven是否安装成功。如能正确输出Maven的安装版本,则表示它安装成功了。
2.maven的setting配置
1.Maven的安装目录的conf子目录下面提供了一个settings.xml文件来定义Maven的全局环境信息。
2.用户.m2子目录下面settings.xml的配置只是针对当前用户。一般情况是没有的,如果需要是允许配置的。
settings.xml中主要包括以下元素:
1.localRepository:表示Maven用来在本地储存信息的本地仓库的目录。默认是用户家目录下面的.m2/repository目录。
2.interactiveMode:表示是否使用交互模式,默认是true;如果设为false,那么当Maven需要用户进行输入的时候,它会使用一个默认值。
3.offline:表示是否离线,默认是false。这个属性表示在Maven进行项目编译和部署等操作时是否允许Maven进行联网来下载所需要的信息。
4.pluginGroups:在pluginGroups元素下面可以定义一系列的pluginGroup元素。表示当通过plugin的前缀来解析plugin的时候到哪里寻找。pluginGroup元素指定的是plugin的groupId。默认情况下,Maven会自动把org.apache.maven.plugins和org.codehaus.mojo添加到pluginGroups下。
5.proxies:其下面可以定义一系列的proxy子元素,表示Maven在进行联网时需要使用到的代理。当设置了多个代理的时候第一个标记active为true的代理将会被使用。
<proxies> 2. <proxy> 3. <id>xxx</id> 4. <active>true</active> 5. <protocol>http</protocol> 6. <username>用户名</username> 7. <password>密码</password> 8. <host>代理服务器地址</host> 9. <port>代理服务器的端口</port> 10. <nonProxyHosts>不使用代理的主机</nonProxyHosts> 11. </proxy> 12.</proxies>
6.servers:其下面可以定义一系列的server子元素,表示当需要连接到一个远程服务器的时候需要使用到的验证方式。这主要有username/password和privateKey/passphrase这两种方式。以下是一个使用servers的示例:
<servers> 2. <server> 3. <id>id</id> 4. <username>用户名</username> 5. <password>密码</password> 6. </server> 7.</servers>
7.mirrors:用于定义一系列的远程仓库的镜像。我们可以在pom中定义一个下载工件的时候所使用的远程仓库。但是有时候这个远程仓库会比较忙,所以这个时候人们就想着给它创建镜像以缓解远程仓库的压力,也就是说会把对远程仓库的请求转换到对其镜像地址的请求。每个远程仓库都会有一个id,这样我们就可以创建自己的mirror来关联到该仓库,那么以后需要从远程仓库下载工件的时候Maven就可以从我们定义好的mirror站点来下载,这可以很好的缓解我们远程仓库的压力。在我们定义的mirror中每个远程仓库都只能有一个mirror与它关联,也就是说你不能同时配置多个mirror的mirrorOf指向同一个repositoryId。
<mirrors> 2. <mirror> 3. <id>mirrorId</id> 4. <mirrorOf>repositoryId</mirrorOf> 5. <name>定义一个容易看懂的名称 </name> 6. <url>http://my.repository.com/repo/path</url> 7. </mirror> 8.</mirrors>
id:是用来区别mirror的,所有的mirror不能有相同的id
mirrorOf:用来表示该mirror是关联的哪一个仓库,其值为其关联仓库的id。当要同时关联多个仓库时,这多个仓库之间可以用逗号隔开;当要关联所有的仓库时,可以使用“”表示;当要关联除某一个仓库以外的其他所有仓库时,可以表示为“,!repositoryId”;当要关联不是localhost或用file请求的仓库时,可以表示为“external:*”。
url:表示该镜像的url。当Maven在建立系统的时候就会使用这个url来连接到我们的远程仓库。
8.profiles:用于指定一系列的profile。profile元素由activation、repositories、pluginRepositories和properties四个元素组成。当一个profile在settings.xml中是处于活动状态并且在pom.xml中定义了一个相同id的profile时,settings.xml中的profile会覆盖pom.xml中的profile。
3.maven创建项目
mvn archetype:generate 这样就可以根据提示来建立一个maven项目
后面可以接很多参数,常用的有:
-DgroupId=com.company.app 组id -DartifactId=app 项目名称,maven会根据这个名称在当前目录下新建一个名为该名称的目录用于建立项目 -DinteractiveMode=false 是否已交互模式进行,如果是false的话就会采用默认设置建立项目
运行:mvn archetype:generate -DgroupId=id -DartifactId=app -DinteractiveMode=false
新建一个名为app的maven项目
运行:mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.myhost.myapp -DartifactId=myapp
新建一个名为myapp 的web项目
4.常见mvn 命令
1.使用mvc compile进行源码编译,编译后的文件将放在项目根目录下的target目录中
2.使用mvc test-compile编译测试源码
3.使用mvc test编译源码和测试源码进行测试,mvc test将先编译源码,再编译测试源码,然后执行测试代码。
4.使用mvn package进行项目打包
在项目所在的目录执行指令mvn package可以进行项目打包,打包方式是在项目根目录下的pom.xml文件中的packaging元素定义的,如果定义为jar则打为jar包,如果是war则打为war包,如果是ear则为ear包。如果pom.xml中没有定义packaging元素,则会使用默认值jar。打包后的文件将会放在项目根目录下的target目录下。打包后的文件名将是在pom.xml文件中定义的artifactId-version的形式,比如在pom.xml中定义的artifactId是hello,定义的version是1.0,则打包后生成的文件的名称将是hello-1.0。
5.使用mvn install安装jar包到maven的本地仓库
使用mvn install可以把mvn package打包好的jar安装到maven的本地仓库。本地仓库默认是在~/.m2/repository,可以在maven安装目录下的conf/settings文件中的localRepository标签中定义本地仓库的路径。
当我们需要安装一个本地jar包到本地资源库的时候我们可以使用“mvn install:install-file”指令,使用该指令时有几个参数需要指定。file:表示本地jar包所在的路径;groupId:表示jar包被安装到本地仓库之后的groupId;artifactId:表示jar包被安装到本地仓库之后的artifactId;version:表示安装到本地仓库之后对应的版本;packging:表示当前组件被引用的类型,既然我们是安装jar包则这里对应的自然是jar了。
使用mvn dependency:tree可以查看项目的依赖关系
修改Maven同时下载artifact的最大数:mvn –Dmaven.artifact.threads=3 install
jar安装到我们的本地仓库,之后我们就可以直接在我们本地的Maven项目中引用该依赖类型了
6.使用mvn deploy可以安装当前项目到远程仓库
7.使用mvn clean可以清除存放临时文件的target目录
8.在断开网络的情况下执行Maven指令
有时候我们连不上网或者我们需要在不访问网络的情况下进行某些操作,这个时候我们就可以在执行Maven指令的时候使用-o参数 如:mvn –o package
9.使用mvn javadoc:jar生成对应的javadoc
10.使用mvn dependency:sources下载对应的源码
5. 把资源文件一并打到jar包中
如果需要把一些资源文件也一并打包到jar包里面的话,需要在${basedir}/src/main 下新建一个resources目录,然后把所有的资源文件都放到这个目录中,这样这些文件都会放到类路径下面。如果需要在测试代码中访问到对应的资源,那么相对的就需要在 ${basedir}/src/test 下新建一个resources目录,然后把相应的资源文件放在这个目录下。
<testResources> <testResource> <directory>src/test/resources/config</directory> <targetPath>${project.build.directory}/config</targetPath> <excludes> <exclude>xxxxxxxxx.xml</exclude> </excludes> <filtering>true</filtering> </testResource> </testResources>
6.配置
—-过滤资源文件
有的时候有些资源文件中的值我们需要在编译的时候动态的指定,maven允许我们在建立文件的时候以${property_name}的方式指定,这样当我们进行编译的时候就会自动的把property_name对应的值替换${property_name}。这个property可以是pom.xml中定义的值,也可以是settings.xml中定义的值,也可以是定义在外部属性文件中的值,还可以是系统属性。maven这种动态替换属性值的功能默认是关闭的,如果要打开的话需要在项目的pom.xml文件中指定filtering的值为true,默认是false。
<testResource> <directory>src/test/resources/config</directory> <targetPath>${project.build.directory}/config</targetPath> <filtering>true</filtering> </testResource>
—-使用pom.xml和settings.xml中的元素element作为属性
我们可以使用pom.xml文件中的element对应的值来作为属性值。在maven中,使用pom来表示pom.xml中的根元素project,所以我们可以使用
project_name=${pom.name} project_version=${pom.version} project_modelVersion=${pom.modelVersion} project_artifactId=${pom.artifactId} settings_localRepository=${settings.localRepository} 如果我们只需要对资源文件进行处理的话也可以使用mvn process-resources指令,该指令是专门用于处理资源文件的,而mvn compile是在编译的时候处理了资源文件。
—-使用外部文件的属性关联
要使用外部文件的属性来关联资源文件里面定义的属性值,那么我们就需要告诉maven应该去哪里找这个属性文件,这是通过在pom.xml中指定filter的值来指定的。
<filters> <filter>src/main/filters/testFilter.properties</filter> </filters>
pom.xml文件内部定义的属性值将具有更高的优先级,它会覆盖外部属性文件中相同的属性定义。
—-使用系统属性
滤资源还可以使用来自系统属性的值,比如java.version,或者在命令行使用-D参数指定的参数。
java_version=${java.version} command.line.prop=${command.line.prop}
执行指令mvn process-resources –Dcommand.line.prop=hello,之后我们可以看到
java_version=1.7.0_07 command.line.prop=hello
—-在pom.xml中定义project的外部依赖包
对于每一个外部依赖都有4个元素是必须定义的,它们是groupId、artifactId、version和scope。其中groupId、artifactId和version必须和依赖包中使用maven打包时定义的pom.xml中定义的相对应的元素的值相同。比如说我们有一个maven项目叫projectA,它的pom.xml中定义的groupId、artifactId和version如下:
<groupId>com.tiantian.projectA</groupId> <artifactId>projectA</artifactId> <version>1.0</version>
之后我们用mvn package把projectA打包为一个jar包,然后使用mvn install把打好的jar包安装到本地仓库。这个时候有另一个项目projectB,它需要在它的pom.xml中定义对projectA的依赖,这个时候它的pom.xml中定义对projectA依赖的groupId、artifactId和version都应该和projectA的pom.xml中定义的保持一致,具体代码如下:
<dependency> <groupId>com.tiantian.projectA</groupId> <artifactId>projectA</artifactId> <version>1.0</version> <scope>running</scope> </dependency>
元素scope的值表示引用的作用范围,主要取值有compile、test、provided、runtime和system。
对于pom.xml中使用dependency定义的引用信息,maven在需要使用的时候会先从本地仓库取,如果在本地仓库取不到的时候就会尝试从远程仓库下载。
7.profile介绍
1)profile简介
profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。
2)profile的定义位置
对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。
(1) 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。
(2)针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户“.m2”目录下。
(3) 全局的profile配置。全局的profile是定义在Maven安装目录下的“conf/settings.xml”文件中的。
3)profile中能定义的信息
profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。
profile定义在settings.xml中
当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有、和。定义在里面的键值对可以在pom.xml中使用。
profile定义在pom.xml中
定义在pom.xml中的profile可以定义更多的信息。主要有以下这些:
<repositories><pluginRepositories><dependencies><plugins><properties><dependencyManagement><distributionManagement>还有build元素下面的子元素,主要包括:<defaultGoal><resources><testResources><finalName>
profile的激活方式
Maven给我们提供了多种不同的profile激活方式。比如我们可以使用-P参数显示的激活一个profile,也可以根据环境条件的设置让它自动激活等。下面将对它们一一进行介绍:
—-使用activeByDefault设置激活
<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <properties> 5. <hello>world</hello> 6. </properties> 7. <activation> 8. <activeByDefault>true</activeByDefault> 9. </activation> 10. </profile> 11. 12. <profile> 13. <id>profileTest2</id> 14. <properties> 15. <hello>andy</hello> 16. </properties> 17. </profile> 18. </profiles>
我们可以在profile中的activation元素中指定激活条件,当没有指定条件,然后指定activeByDefault为true的时候就表示当没有指定其他profile为激活状态时,该profile就默认会被激活。所以当我们调用mvn package的时候上面的profileTest1将会被激活,但是当我们使用mvn package –P profileTest2的时候将激活profileTest2,而这个时候profileTest1将不会被激活。
—-在settings.xml中使用activeProfiles指定处于激活状态的profile
我们可以在settings.xml中使用activeProfiles来指定需要激活的profile,这种方式激活的profile将所有情况下都处于激活状态。比如现在我们定义了如下两个profile
<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <properties> 5. <hello>world</hello> 6. </properties> 7. </profile> 8. 9. <profile> 10. <id>profileTest2</id> 11. <properties> 12. <hello>andy</hello> 13. </properties> 14. </profile> 15.</profiles>
这里的profile可以是定义在settings.xml中的,也可以是定义在pom.xml中的。这个时候如果我们需要指定profileTest1为激活状态,那么我们就可以在settings.xml中定义activeProfiles,具体定义如下:
1.<activeProfiles> 2. <activeProfile>profileTest1</activeProfile> 3.</activeProfiles>
考虑这样一种情况,我们在activeProfiles下同时定义了多个需要激活的profile。这里还拿上面的profile定义来举例,我们定义了同时激活profileTest1和profileTest2。
1.<activeProfiles> 2. <activeProfile>profileTest1</activeProfile> 3. <activeProfile>profileTest2</activeProfile> 4.</activeProfiles>
从profileTest1和profileTest2我们可以看出它们共同定义了属性hello。那么这个时候我在pom.xml中使用属性hello的时候,它到底取的哪个值呢?是根据activeProfile定义的顺序,后面的覆盖前面的吗?根据我的测试,答案是非也,它是根据profile定义的先后顺序来进行覆盖取值的,然后后面定义的会覆盖前面定义的。
—-使用-P参数显示的激活一个profile
假设我们现在有如下定义的profiles
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <properties> 5. <hello>world</hello> 6. </properties> 7. </profile> 8. <profile> 9. <id>profileTest2</id> 10. <properties> 11. <hello>andy</hello> 12. </properties> 13. </profile> 14.<profiles>
那么当我们在进行Maven操作时就可以使用-P参数显示的指定当前激活的是哪一个profile了。比如我们需要在对项目进行打包的时候使用id为profileTest1的profile,我们就可以这样做:
mvn package –P profileTest1
当我们使用activeByDefault或settings.xml中定义了处于激活的profile,但是当我们在进行某些操作的时候又不想它处于激活状态,这个时候我们可以这样做:
Mvn package –P !profileTest1
这里假设profileTest1是在settings.xml中使用activeProfile标记的处于激活状态的profile,那么当我们使用“-P !profile”的时候就表示在当前操作中该profile将不处于激活状态。
—-根据环境来激活profile
profile一个非常重要的特性就是它可以根据不同的环境来激活,比如说根据操作系统的不同激活不同的profile,也可以根据jdk版本的不同激活不同的profile,等等。
vvvvvvvvvvvvvvvvvvv根据jdk来激活profile
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <jdk>1.5</jdk> 5. </profile> 6.<profiles> 上面情况表示在jdk为1.5版本系列的时候激活profileTest1。
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <jdk>[1.4,1.7)</jdk> 5. </profile> 6.<profiles> 上面的情况表示在jdk为1.4、1.5和1.6的时候激活profileTest1。
vvvvvvvvvvvvvvvvvvv根据操作系统来激活profile
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <activation> 5. <os> 6. <name>Windows XP</name> 7. <family>Windows</family> 8. <arch>x86</arch> 9. <version>5.1.2600</version> 10. </os> 11. </activation> 12. </profile> 13.</profiles>
vvvvvvvvvvvvvvvvvvv根据系统属性来激活profile
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <activation> 5. <property> 6. <name>hello</name> 7. <value>world</value> 8. </property> 9. </activation> 10. </profile> 11.</profiles>
上面的profileTest1将在提供了系统属性hello,并且其值为world的时候激活。下面的做法可以激活profileTest1:
mvn package –Dhello=world
当是下面的这种定义形式时,profileTest1将在指定了系统属性hello,且其值为任意值的时候被激活。
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <activation> 5. <property> 6. <name>hello</name> 7. </property> 8. </activation> 9. </profile> 10.</profiles>
vvvvvvvvvvvvvvvvvvv根据文件是否存在激活profile
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <activation> 5. <file> 6. <exists>target</exists> 7. </file> 8. </activation> 9. </profile> 10.</profiles> 上面的定义表示当存在target文件时激活profileTest1。
—-查看当前处于激活状态的profile
我们可以同时定义多个profile,那么在建立项目的过程中,到底激活的是哪一个profile呢?Maven为我们提供了一个指令可以查看当前处于激活状态的profile都有哪些,这个指定就是mvn help:active-profiles。
现在假设我们的settings.xml文件中有如下profile的定义:
1.<profiles> 2. <profile> 3. <id>profileTest1</id> 4. <activation> 5. <file> 6. <missing>target</missing> 7. </file> 8. </activation> 9. </profile> 10.</profiles> 11. 12.<activeProfiles> 13. <activeProfile>profileTest1</activeProfile> 14.</activeProfiles>
这个时候我们可以看到,我们已经定义了profileTest1始终为激活状态,这个时候我们使用mvn help:active-profiles查看处于激活状态的profile时,就会打印出如下内容:
8.Maven仓库介绍
简介
Maven仓库是用来存储工件的。Maven仓库主要包括本地仓库和远程仓库。当Maven需要一个工件的时候,它会先从本地仓库取,只有在本地仓库不存在对应的工件的时候,才会从远程仓库把对应的工件下载下来保存在本地仓库,并从本地仓库获取所需的工件。默认的本地仓库位置是用户家目录下面的“.m2/repository”,我们可以在Maven安装目录下面的settings.xml文件中通过localRepository定义本地仓库的位置。默认的远程仓库是“http://repo.maven.apache.org/maven2/”。
在这里我想陈述一个问题,Maven官方是不主张我们在使用Maven的时候还把项目依赖的一些jar包提交到svn等版本控制系统中进行版本控制。这主要有以下原因:
1) 我们已经使用了Maven来管理我们的依赖jar包,那么这些jar包就都会保存在本地仓库中,我们没有必要每个项目都保存一个依赖jar包的拷贝,这会浪费很多的磁盘空间,也违背了Maven设计的初衷。
2) 当我们没有把依赖的jar包提交到版本控制系统的时候,这也就意味着我们这个项目的容量会相对而言小一些,这给我们带来的优点就是在我们检出该项目的时候速度会相对而言更快一些。
3) Jar包一般都不需要进行版本控制,因为它的变化一般不大,我们很少会去更改一个jar包。
有的时候因为安全或者速度的原因,我们不允许直接从互联网上下载依赖的jar包,这个时候内部的仓库就出来了。我们可以从这个内部仓库下载工件,也可以把工件发布到该仓库。这个内部仓库的概念就相当于是公司内部自己管理了一套工件库,而且可以自由的往这个工件库里面发布公司自己的工件供大家共享。
安装第三方jar包到本地仓库
mvn install:install-file -Dfile=<filePath> -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=<version> -Dpackaging=<packagingType>
参数file表示需要安装的第三方jar包在本地的路径; 参数groupId用于定义该jar包安装后的groupId; 参数artifactId用于定义该jar包安装后的artifactId; 参数version用于定义该jar包安装后的版本; 参数packaging用于定义该jar包安装后的打包类型。 比如现在我想把我电脑上的“D:\develop\lib\mysql-connector-java-5.1.12-bin.jar”安装到我的Maven本地仓库,那么我就可以在命令窗口运行以下指令来达到这个目的: mvn install:install-file -Dfile=D:\develop\lib\mysql-connector-5.1.12-bin.jar -DgroupId=mysql -DartifactId=mysql -Dversion=5.1.12 -Dpackaging=jar 之后在其他Maven项目中我们就可以根据定义好的groupId、artifactId、version和packaging类型来添加这里定义好的mysql-connector-5.1.12-bin.jar的引用了。
部署第三方jar包到远程仓库
前面安装到本地仓库的第三方jar包只能是在本地使用,这样其他人是无法访问到的。如果需要其他人也能访问到的话,我们就需要把它部署到我们的远程仓库上去。我们可以使用以下Maven指令来部署一个第三方jar包到指定的远程仓库。
1.mvn deploy:deploy-file 2. -Dfile=<filePath> 3. -DgroupId=<groupId> 4. -DartifactId=<artifactId> 5. -Dversion=<version> 6. -Dpackaging=<packagingType> 7. -DrepositoryId=<repositoryId> 8. -Durl=<urlOfTheRepositoryToDeploy>
把第三方jar包部署到远程仓库的参数和安装第三方jar包到本地仓库类似,但它多了两个参数,一个是repositoryId和url。repositoryId表示需要部署到的远程仓库的id,这个远程仓库是定义在settings.xml中的;url表示需要部署到的远程仓库的url。
默认情况下,使用deploy:deploy-file部署的第三方jar包将会生成一个通用的pom。如果在部署的过程中不需要生成这个pom,我们可以在使用该指令的时候加上参数“-DgeneratePom=false”。
如果我们在使用deploy:deploy-file部署第三方jar到远程仓库需要使用一个已有的pom的时候,我们需要在使用该指令的时候加上参数“-DpomFile=”。如:
1.mvn deploy:deploy-file 2. -Dfile=<filePath> 3. -DpomFile=<pomFilePath> 4. -DrepositoryId=<repositoryId> 5. -Durl=<urlOfTheRepositoryToDeploy>
细心的读者可能已经发现了,我们在使用了参数pomFile的时候没有指定groupId、artifactId、version和packaging参数。这是因为当我们指定了pomFile的时候这些参数都可以从指定的pom文件中获得。
当我们需要部署的是一个源码jar包的时候,packaging应该指定为java-source,而且generatePom应该指定为false。
9.Maven的pom.xml介绍
简介
pom.xml文件是Maven进行工作的主要配置文件。在这个文件中我们可以配置Maven项目的groupId、artifactId和version等Maven项目必须的元素;可以配置Maven项目需要使用的远程仓库;可以定义Maven项目打包的形式;可以定义Maven项目的资源依赖关系等等。对于一个最简单的pom.xml的定义必须包含modelVersion、groupId、artifactId和version这四个元素,当然这其中的元素也是可以从它的父项目中继承的。在Maven中,使用groupId、artifactId和version组成groupdId:artifactId:version的形式来唯一确定一个项目。
pom.xml的继承、聚合与依赖
我们知道Maven在建立项目的时候是基于Maven项目下的pom.xml进行的,我们项目依赖的信息和一些基本信息都是在这个文件里面定义的。那如果当我们有多个项目要进行,这多个项目有些配置内容是相同的,有些是要彼此关联的,那如果按照传统的做法的话我们就需要在多个项目中都定义这些重复的内容。这无疑是非常耗费时间和不易维护的。好在Maven给我们提供了一个pom的继承和聚合的功能。
对于使用java的人而言,继承这个词大家应该都不陌生。要继承pom就需要有一个父pom,在Maven中定义了超级pom.xml,任何没有申明自己父pom.xml的pom.xml都将默认继承自这个超级pom.xml。
和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是:
Ø dependenciesØ developersØ contributorsØ plugin列表,包括plugin下面的reportsØ resources
vvvvvvvvvvvvvvvv继承
1被继承项目与继承项目是父子目录关系
1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3. <parent> 4. <groupId>com.tiantian.mavenTest</groupId> 5. <artifactId>projectA</artifactId> 6. <version>1.0-SNAPSHOT</version> 7. </parent> 8. <modelVersion>4.0.0</modelVersion> 9. <groupId>com.tiantian.mavenTest</groupId> 10. <artifactId>projectB</artifactId> 11. <packaging>jar</packaging> 12. <version>1.0-SNAPSHOT</version> 13.</project> 由projectB的pom.xml文件的定义我们可以知道,当需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。
2被继承项目与继承项目的目录结构不是父子关系
当被继承项目与继承项目的目录结构不是父子关系的时候,我们再利用上面的配置是不能实现Maven项目的继承关系的,这个时候我们就需要在子项目的pom.xml文件定义中的parent元素下再加上一个relativePath元素的定义,用以描述父项目的pom.xml文件相对于子项目的pom.xml文件的位置。
在projectA的子目录中,而是与projectA处于同一目录中。这个时候projectA和projectB的目录结构如下: ------projectA ------pom.xml ------projectB ------pom.xml 这个时候我们可以看出projectA的pom.xml相对于projectB的pom.xml的位置是“../projectA/pom.xml”,所以这个时候projectB的pom.xml的定义应该如下所示:1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3. <parent> 4. <groupId>com.tiantian.mavenTest</groupId> 5. <artifactId>projectA</artifactId> 6. <version>1.0-SNAPSHOT</version> 7. <relativePath>../projectA/pom.xml</relativePath> 8. </parent> 9. <modelVersion>4.0.0</modelVersion> 10. <groupId>com.tiantian.mavenTest</groupId> 11. <artifactId>projectB</artifactId> 12. <packaging>jar</packaging> 13. <version>1.0-SNAPSHOT</version> 14.</project>
vvvvvvvvvvvvvvvvv聚合
对于聚合这个概念搞java的人应该都不会陌生。先来说说我对聚合和被聚合的理解,比如说如果projectA聚合到projectB,那么我们就可以说projectA是projectB的子模块, projectB是被聚合项目,也可以类似于继承那样称为父项目。对于聚合而言,这个主体应该是被聚合的项目。所以,我们需要在被聚合的项目中定义它的子模块,而不是像继承那样在子项目中定义父项目。具体做法是:
Ø 修改被聚合项目的pom.xml中的packaging元素的值为pom
Ø 在被聚合项目的pom.xml中的modules元素下指定它的子模块项目
对于聚合而言,当我们在被聚合的项目上使用Maven命令时,实际上这些命令都会在它的子模块项目上使用。这就是Maven中聚合的一个非常重要的作用。假设这样一种情况,你同时需要打包或者编译projectA、projectB、projectC和projectD,按照正常的逻辑我们一个一个项目去使用mvn compile或mvn package进行编译和打包,对于使用Maven而言,你还是这样使用的话是非常麻烦的。因为Maven给我们提供了聚合的功能。我们只需要再定义一个超级项目,然后在超级项目的pom.xml中定义这个几个项目都是聚合到这个超级项目的。之后我们只需要对这个超级项目进行mvn compile,它就会把那些子模块项目都进行编译。
1.被聚合项目和子模块项目在目录结构上是父子关系
还拿上面定义的projectA和projectB来举例子,现在假设我们需要把projectB聚合到projectA中。projectA和projectB的目录结构如下所示:------projectA ------projectB -----pom.xml ------pom.xml这个时候projectA的pom.xml应该这样定义:1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3. <modelVersion>4.0.0</modelVersion> 4. <groupId>com.tiantian.mavenTest</groupId> 5. <artifactId>projectA</artifactId> 6. <version>1.0-SNAPSHOT</version> 7. <packaging>pom</packaging> 8. <modules> 9. <module>projectB</module> 10. </modules> 11.</project> 由上面的定义我们可以看到被聚合的项目的packaging类型应该为pom,而且一个项目可以有多个子模块项目。对于聚合这种情况,我们使用子模块项目的artifactId来作为module的值,表示子模块项目相对于被聚合项目的地址,在上面的示例中就表示子模块projectB是处在被聚合项目的子目录下,即与被聚合项目的pom.xml处于同一目录。这里使用的module值是子模块projectB对应的目录名projectB,而不是子模块对应的artifactId。这个时候当我们对projectA进行mvn package命令时,实际上Maven也会对projectB进行打包。
2被聚合项目与子模块项目在目录结构上不是父子关系
那么当被聚合项目与子模块项目在目录结构上不是父子关系的时候,我们应该怎么来进行聚合呢?还是像继承那样使用relativePath元素吗?答案是非也,具体做法是在module元素中指定以相对路径的方式指定子模块。我们来看下面一个例子。继续使用上面的projectA和projectB,还是需要把projectB聚合到projectA,但是projectA和projectB的目录结构不再是父子关系,而是如下所示的这种关系:------projectA ------pom.xml------projectB ------pom.xml这个时候projectA的pom.xml文件就应该这样定义:1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3. <modelVersion>4.0.0</modelVersion> 4. 5. <groupId>com.tiantian.mavenTest</groupId> 6. <artifactId>projectA</artifactId> 7. <version>1.0-SNAPSHOT</version> 8. <packaging>pom</packaging> 9. <modules> 10. <module>../projectB</module> 11. </modules> 12.</project> 注意看module的值是“../projectB”,我们知道“..”是代表当前目录的上层目录,所以它表示子模块projectB是被聚合项目projectA的pom.xml文件所在目录(即projectA)的上层目录下面的子目录,即与projectA处于同一目录层次。注意,这里的projectB对应的是projectB这个项目的目录名称,而不是它的artifactId。
3聚合与继承同时进行
假设有这样一种情况,有两个项目,projectA和projectB,现在我们需要projectB继承projectA,同时需要把projectB聚合到projectA。然后projectA和projectB的目录结构如下: ------projectA ------pom.xml ------projectB ------pom.xml 那么这个时候按照上面说的那样,projectA的pom.xml中需要定义它的packaging为pom,需要定义它的modules,所以projectA的pom.xml应该这样定义:1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3. <modelVersion>4.0.0</modelVersion> 4. <groupId>com.tiantian.mavenTest</groupId> 5. <artifactId>projectA</artifactId> 6. <version>1.0-SNAPSHOT</version> 7. <packaging>pom</packaging> 8. <modules> 9. <module>../projectB</module> 10. </modules> 11.</project> 而projectB是继承自projectA的,所以我们需要在projectB的pom.xml文件中新增一个parent元素,用以定义它继承的项目信息。所以projectB的pom.xml文件的内容应该这样定义:1.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3. <modelVersion>4.0.0</modelVersion> 4. <parent> 5. <groupId>com.tiantian.mavenTest</groupId> 6. <artifactId>projectA</artifactId> 7. <version>1.0-SNAPSHOT</version> 8. <relativePath>../projectA/pom.xml</relativePath> 9. </parent> 10. <groupId>com.tiantian.mavenTest</groupId> 11. <artifactId>projectB</artifactId> 12. <version>1.0-SNAPSHOT</version> 13. <packaging>jar</packaging> 14.</project>
vvvvvvvvvvvvvvvvvvvvvvv依赖Dependency
项目之间的依赖是通过pom.xml文件里面的dependencies元素下面的dependency元素进行的。一个dependency元素定义一个依赖关系。在dependency元素中我们主要通过依赖项目的groupId、artifactId和version来定义所依赖的项目。
先来看一个简单的项目依赖的示例吧,假设我现在有一个项目projectA,然后它里面有对junit的依赖,那么它的pom.xml就类似以下这个样子:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> <optional>true</optional> </dependency> </dependencies>
在dependency元素中除了可以指定依赖项目的groupId、artifactId和version之外,还可以指定以下元素:
Ø type:对应于依赖项目的packaging类型,默认是jar
Ø scope:表示依赖项目的一个作用范围。scope的主要取值范围如下
compile:这是它的默认值,这种类型很容易让人产生误解,以为只有在编译的时候才是需要的,其实这种类型表示所有的情况都是有用的,包括编译和运行时。而且这种类型的依赖性是可以传递的。 provided:这个跟compile很类似,但是它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。 runtime:这种类型表示该依赖在编译的时候不是必须的,只有在运行的时候才是必须的。 test:这表示这种依赖只有测试的时候才需要,正常情况下是不需要的。 system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径。
Ø systemPath:上面已经说过了这个元素是在scope的值为system的时候用于指定依赖的jar包在系统上的位置的,而且是绝对路径。该元素必须在依赖的 jar包的scope为system时才能使用,否则Maven将报错。
Ø optional:当该项目本身作为其他项目的一个依赖时标记该依赖为可选项。假设现在projectA有一个依赖性projectB,我们把projectB这个依赖项设为optional,这表示projectB在projectA的运行时不一定会用到。这个时候如果我们有另一个项目projectC,它依赖于projectA,那么这个时候因为projectB对于projectA是可选的,所以Maven在建立projectC的时候就不会安装projectB,这个时候如果projectC确实需要使用到projectB,那么它就可以定义自己对projectB的依赖。当一个依赖是可选的时候,我们把optional元素的值设为true,否则就不设置optional元素。
Ø exclusions:考虑这样一种情况,我们的projectA依赖于projectB,然后projectB又依赖于projectC,但是在projectA里面我们不需要projectB依赖的projectC,那么这个时候我们就可以在依赖projectB的时候使用exclusions元素下面的exclusion排除projectC。这个时候我们可以这样定义projectA对projectB的依赖:
1.<dependencies> 2. <dependency> 3. <groupId>com.tiantian.mavenTest</groupId> 4. <artifactId>projectB</artifactId> 5. <version>1.0-SNAPSHOT</version> 6. <exclusions> 7. <exclusion> 8. <groupId>com.tiantian.mavenTest</groupId> 9. <artifactId>projectC</artifactId> 10. </exclusion> 11. </exclusions> 12. </dependency> 13.</dependencies>
dependencyManagement介绍
dependencyManagement主要有两个作用,一个是集中管理项目的依赖项,另一个就是控制使用的依赖项的版本。
内容来自:http://elim.iteye.com/blog
- Maven
- Maven
- Maven
- maven
- Maven
- Maven
- maven
- maven
- maven
- maven
- Maven
- maven .
- Maven
- maven
- maven
- maven
- MAVEN
- Maven
- 29个nmap使用技巧
- C++ Primer Plus 编程练习 第二章
- Android使用OKHTTP网络框架请求数据,RecyclerView结合Glide展示图片,瀑布流布局样式
- Oracle中varchar2(4000)最多能存多少个汉字?
- Web接口测试工具--Jmeter
- Maven
- 更新一个文件夹下所有的文件
- Java调用MATLAB程序打包的jar包时出现错误MWEException
- local git link romote github
- KCF目标跟踪代码及注释
- css3软键盘不盖住输入框的方法
- opecv常用绘制函数
- 用lambda简化代码
- QT配置第三方库