如何使用 maven classifier作用

博客访问: 49138
博文数量: 36
博客积分: 647
博客等级: 上士
技术积分: 290
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Delphi
1、排除传递依赖解决版本冲突,传递依赖包获取不到等问题确定是哪个包的传递依赖产生的冲突&:&首先,你要在pom.xml中加上maven-project-info-reports-plugin插件。&project&&reporting&...&/reporting&&/project&&reporting&&&&plugins&&&&&plugin&&&&&&groupId&org.apache.maven.plugins&/groupId&&&&&&artifactId&&&&&&maven-project-info-reports-plugin&&&&&/artifactId&&&&&/plugin&& &/plugins&&&&/reporting&&然后再执行:mvn project-info-reports:dependencies 。生成项目依赖树,在target/site/dependencies.html可以查看项目依赖关系,最后在相应的dependency中加上exclusions来排除相关的传递依赖。例:在本例中,jmxtools在本地远程仓库中是丢失,所以采取该方式排除掉& &dependencies&& & &dependency&& & & &groupId&log4j&/groupId&& & & &artifactId&log4j&/artifactId&& & & &version&1.2.15&/version&& & & &exclusions&& & & &&exclusion&& & & & &groupId&com.sun.jdmk&/groupId&& & & & &artifactId&jmxtools&/artifactId&& & & &&/exclusion&& & & &/exclusions&& & &/dependency&2、生成项目站点:其实生产报表文件,可以如下比如:在&project&&build&标签下加入如下代码:& & & & &pluginManagement&& & & & & & &plugins&& & & & & & & & &plugin&& & & & & & & & & & &groupId&org.apache.maven.plugins&/groupId&& & & & & & & & & & &artifactId&maven-site-plugin&/artifactId&& & & & & & & & & & &version&3.0-beta-3&/version&& & & & & & & & & & &configuration&& & & & & & & & & & & & &reportPlugins&& & & & & & & & & & & & & & &plugin&& & & & & & & & & & & & & & & & &groupId&org.apache.maven.plugins&/groupId&& & & & & & & & & & & & & & & & &artifactId&maven-checkstyle-plugin&/artifactId&& & & & & & & & & & & & & & &/plugin&& & & & & & & & & & & & & & &plugin&& & & & & & & & & & & & & & & & &groupId&org.apache.maven.plugins&/groupId&& & & & & & & & & & & & & & & & &artifactId&maven-project-info-reports-plugin&/artifactId&& & & & & & & & & & & & & & & & &version&2.4&/version&& & & & & & & & & & & & & & & & &configuration&& & & & & & & & & & & & & & & & & & &dependencyDetailsEnabled&true&/dependencyDetailsEnabled&& & & & & & & & & & & & & & & & & & &dependencyLocationsEnabled&false&/dependencyLocationsEnabled&& & & & & & & & & & & & & & & & &/configuration&& & & & & & & & & & & & & & &/plugin&& & & & & & & & & & & & &/reportPlugins&& & & & & & & & & & &/configuration&& & & & & & & & &/plugin&& & & & & & &/plugins&& & & & &/pluginManagement&每一个plugin产生一种类型的报表3.项目统一的本地远程maven repository 配置M2_HOME/conf/settings.xml&settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"& & & & & xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"& & & & & xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"&& &mirrors&& & &mirror&& & & &mirrorOf&*&/mirrorOf&& & & &name&repo&/name&& & & &url&http://ip:8081/artifactory/repo&/url&& & &/mirror&& &/mirrors&4.&如何忽略测试步骤给mvn增加命令行参数&-Dmaven.test.skip=true&或者&-DskipTests=true&mvn -Dmaven.test.skip=true package (单元测试有错误,略过测试步骤)5. property定义1)直接在pom.xml定义property&project&...
&properties&
&my.filter.value&hello&/my.filter.value&
&/properties&...&/project&2)引用外部文件的property首先:创建外部属性文件比如: src/main/filters/filter.properties# filter.properties
my.filter.value=hello!再在pom.xml中引用该外部文件
&filter&src/main/filters/filter.properties&/filter&
&/filters&
&resources&
&resource&
&directory&src/main/resources&/directory&
&filtering&true&/filtering&
&/resource&
&/resources&
&/build&这样就可以在属性文件中引用属性:my.filter.value比如属性文件:src/main/resources/application.properties# application.properties
application.name=${pom.name}
application.version=${pom.version}
message=${my.filter.value}replace property using value&in the resource file, must set "filtering=true" in pom.xml when copy resources.
&resources&
&resource&
&directory&src/main/resources&/directory&
&filtering&true&/filtering&
&/resource&
&/resources&
6. 使用maven-assembly plugin 实现自定义打包。修改pom.xml& & & & & & & & &&plugins&& & & & & & & & & & & & &plugin&& & & & & & & & & & & & & & & & &groupId&org.apache.maven.plugins&/groupId&& & & & & & & & & & & & & & & & &artifactId&maven-assembly-plugin&/artifactId& && & & & & & & & & & & & & & & & &version&2.2.1&/version&& & & & & & & & & & & & & & & & &configuration&& & & & & & & & & & & & & & & & & & & & &descriptorRefs&& & & & & & & & & & & & & & & & & & & & & & & & &descriptorRef&src&/descriptorRef&& & & & & & & & & & & & & & & & & & & & &/descriptorRefs&& & & & & & & & & & & & & & & & &/configuration&& & & & & & & & & & & & & & & & &executions& & &&&&& & & & & & & & & & & & & & & & & & & & &execution&& & & & & & & & & & & & & & & & & & & & & & & & &id&make-assembly&/id& &&&!--名字任意&--&& & & & & & & & & & & & & & & & & & & & & & & & &phase&package&/phase& &&& &&& & & & & & & & & & & & & & & & & & & & & & & & &goals&& & & & & & & & & & & & & & & & & & & & & & & & & & & & &goal&single&/goal& && &&& & & & & & & & & & & & & & & & & & & & & & & & &/goals&& & & & & & & & & & & & & & & & & & & & &/execution&& & & & & & & & & & & & & & & & &/executions&& & & & & & & & & & & & &/plugin&& & & & & & & & &/plugins&  execution的设置是为了将maven-assembly-plugin继承到标准的maven打包过程中,这样在运行maven-package时就会执行maven-assembly-plugin的操作,从而实现我们需要的自定义打包。
这样将打src目录打包,生成的打包文件有3种后缀格式: *-src.tar.bz2,*-src.tar.gz, *src.zip。默认打包到target 目录实际上可以设置配置打包的方式: 在上面代码&&configuration&中加入descriptor属性,例如:          &descriptors&
&&            &descriptor&src/main/assemble/package.xml&/descriptor&          &/descriptors&容许使用多个配置文件,package.xml文件内容参考如下:
&assemblyxmlns="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.0http://maven.apache.org/xsd/assembly-1.0.0.xsd"&  &id&package&/id&  &formats& &&!--设置打包格式 --&    &format&zip&/format&  &/formats&  &includeBaseDirectory&true&/includeBaseDirectory&  &fileSets&    &fileSet& &&!-- 设置要打包的原始目录和结果目录 --&      &directory&src/main/bin&/directory&      &outputDirectory&/&/outputDirectory&    &/fileSet& & &!--&将src/main/bin目录下的文件打包到根目录(/)下. --&    &fileSet&      &directory&src/main/config&/directory&      &outputDirectory&config&/outputDirectory&    &/fileSet&  &/fileSets&  &dependencySets& &!--&将scope为runtime的依赖包打包到lib目录下 --&    &dependencySet&      &outputDirectory&lib&/outputDirectory&      &scope&runtime&/scope&    &/dependencySet&  &/dependencySets&&/assembly&7. 自定义goal, 开发plugin 参考官方文档:8. 部署到服务器,mvn deploy&distributionManagement&
&repository&
&id&proficio-repository&id&
&name&Proficio Repository&name&
&url&file://${basedir}/target/deploy&url&
&repository&
&distributionManagement&9. 导入到eclipse安装m2eclipse plugin &对项目执行mvn eclipse:eclipse再导入到eclipse。可以直接在eclipse创建maven project10.开发自定义goal,即开发插件maven plugin实现goal,每一个mojo对应一个goal例如:Step1:创建插件项目mvn archetype:create -DgroupId=org.sonatype.mavenbook.plugins -DartifactId=first-maven-plugin -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-mojo
Step2:创建Mojo类package com.import org.apache.maven.plugin.AbstractMimport org.apache.maven.plugin.MojoExecutionE/**&* Say hello to user.&*&* @goal sayhi&*/public class MyMojo extends AbstractMojo{& /**& &* Any Object to print out.& &*&& &* @parameter expression="${echo.message}" default-value="Hello Maven World"& &*/& & private O& & public void execute()& & & & throws MojoExecutionException& & {& & & & getLog().info(message.toString());& & }}@goal sayhello &指明goal名称@parameter expression="${echo.message}" default-value="Hello Maven World" &传递参展Step3:&run 自定义插件mvn install插件运行遵循groupId:artifactId:version:goal格式
mvn com.doris:first-maven-plugin:1.0:sayhi -Decho.message=r3r23r3t输出“r3r23r3t” 在屏幕上Step4:其他项目调用该goal,只要在项目中加入以下:&build&& ...& & &plugins&& & & &plugin&& & & & &groupId&com.doris&/groupId&& & & & &artifactId&first-maven-plugin&/artifactId&& & & & &version&1.0&/version& & & & && & & &/plugin&& & &/plugins&...& &/build&Step5: 定义前缀,减短输入命令行长度在.m2/settings.xml中加入&pluginGroups&& &pluginGroup&com.doris&/pluginGroup&&/pluginGroups&you follow the convention of using&${prefix}-maven-plugin&(or&maven-${prefix}-plugin),then can run: "mvn first:sayhi"参考:Step6: 在eclipse中运行自定义goal依次选择:Run as --& &run Configuration.. -& Main tab栏填写: Goals: first:sayhi, (在定义前缀的情况下,可以剪短输入的goal,否则输入groupId:artifactId:version:goal)& & & & & &Parameters name: & message & value: Hi, I am coming!11. how to deploy my jar to remote repositoryFor deploying jars to an external repository, you have to configure the repository url in the pom.xml and the authentication information for connectiong to the repository in the settings.xm
&distributionManagement&
&repository&
&id&drutt-release&/id&
&name&/release&/name&
&url&:8081/artifactory/libs-release-local&/url&
&/repository&
&snapshotRepository&
&id&drutt-snapshot&/id&
&name&/snapshots&/name&
&url&:8081/artifactory/libs-snapshot-local&/url&
&/snapshotRepository&
&/distributionManagement&
[settings.xml]
&id&drutt-release&/id&...
&/servers&12.参考书籍&
13.生成附属构件默认Maven只生成一个构件,我们称之为主构件,那当我们希望Maven生成其他附属构件的时候,就能用上classifier。常见的classifier还有如dog-cli-1.0-sources.jar表示源码包,dog-cli-1.0-javadoc.jar表示JavaDoc包等等。制作classifier的方式多种多样,其中最重要的一种是使用。14.&maven的变量maven定义了很多变量属性,参考&内置属性${basedir&} represents the directory containing pom.xml${version&} equivalent to&${project.version&} or&${pom.version&}Pom/Project properties&所有pom中的元素都可以用&project.&前缀进行引用,以下是部分常用的${project.build.directory&} results in the path to your "target" dir, this is the same as&${pom.project.build.directory&}${project.build.&outputD&irectory&}&results in the path to your "target/classes" dir${project.name&} refers to the name of the project.${project.version&} refers to the version of the project.${project.build.finalName&} refers to the final name of the file created when the built project is packaged本地用户设定&所有用的的 settings.xml 中的设定都可以通过&settings.&前缀进行引用${settings.localRepository&} refers to the path of the user's local repository.${maven.repo.local&} also works for backward compatibility with maven1 ??环境变量&系统的环境变量通过&env.&前缀引用${env.M2_HOME&} returns the Maven2 installation path.${java.home&} specifies the path to the current JRE_HOME environment use with relative paths to get for example:&&jvm&${java.home}../bin/java.exe&/jvm&java系统属性&所有JVM中定义的java系统属性.用户在pom中定义的自定义属性&project&&&&& ...&&&&&&properties&&&&&&&&&&&my.filter.value&hello&/my.filter.value&&&&&&&/properties&&&&& ...&&/project&&则引用 ${my.filter.value&} 就会得到值&hello&上级工程的变量&上级工程的pom中的变量用前缀&${project.parent&} 引用. 上级工程的版本也可以这样引用:&${parent.version&}.15. mvn releaserelease plugin &dry run: don't checkin or tag anything in the scm repository, or modify the checkout. Running&mvn -DdryRun=true release:prepare&is useful in order to check that modifications to poms and scm operations (only listed on the console) are working as expected
16.&&【转】关于maven可选依赖和排除依赖的学习& &了解可选依赖和排除依赖的功能,能够帮助我们更好的理解依赖是什么、怎样使用、如何工作和何时最适宜应用。其中,排除依赖是作为依赖的基本概念而不是处于pom层。一、& &&可选依赖&&&&&&&当一个项目不适合分割成多个子模块的时候,我们可以使用可选依赖。它的思想在于某些依赖只应用于某些功能,而且当没有该功能时也不存在该依赖。理想状况下,一个功能可能被划分为一个子模块,该子模块是一个只有核心功能的项目,由于当你要使用这个子工程的功能的时候,你会需要它的全部,所以这个子工程只含有非可选性依赖。&&&&& 然而,如果工程不可被分割,这些依赖被声明为可选。如果一个用户想要使用和可选性依赖相关的功能,他们必须要在工程中重新声明可选性依赖。也许可选依赖和排除依赖不是解决问题的最好方法,但是不失为一种有效的解决方案。&&&&& 1. 为何使用可选依赖&&&&& 声明可选依赖不仅对于节省空间/内存等是重要的,而且对于使用一个工程的时候控制实际依赖的列表也是非常重要的。因为jar包最终可能编译成WAR、EAR、EJB等等,包含错误的jar包可能产生违反许可证协议、导致类路径错误等问题。&&&&& 2.如何使用optional标记&&&&& 在你的依赖声明中简单地将&optional&标记设置成true,就能将一个依赖声明为可选的。示例如下&project&& ...& &dependencies&&&& &!-- declare the dependency to be set as optional --&&&& &dependency&&&&&& &groupId&sample.ProjectA&/groupId&&&&&& &artifactId&Project-A&/artifactId&&&&& &&version&1.0&/version&&&&&& &scope&compile&/scope&&&&&& &optional&true&/optional& &!-- value will be true or false only --&&&& &/dependency&& &/dependencies&&/project&&&&&& 3.可选依赖是如何工作的?Project-A -& Project-B&&&&& 如上图所以projectA依赖projectB,当A在它的pom中声明B作为它的可选依赖时,这个关系会一直保持。 这就像在通常的构建中,projectB会被加到它的类路径中。Project-X -& Project-A&&&&& 但是当另外一个工程projectX在它的pom中声明A作为其依赖时,可选性依赖这时就发挥作用了。你会发现projectB并不存在projectX的类路径中。如果X的类路径要包含B那么需要在你的pom中直接进行声明。&&&&& 4.例子:&&&&& 让我们假设现在有这样一个和Hibernate有类似功能的工程X2,支持多种诸如mysql, postgre, oracle等数据库驱动/依赖,所有这些驱动/依赖是X2但不是你的工程所需要的,所以一种比较可行的方法就是X2将这些驱动/依赖声明为可选的。这样,无论任何时候当你的工程在pom中声明X2作为直接依赖,X2所支持的这些驱动/依赖都不会被自动加到你工程的类路径中,相反地,你必须要直接声明需要使用的数据库驱动/依赖。二、&&排除依赖&&&&&& 由于maven2.x会传递解析依赖,所以很有可能一些你不需要的依赖也会包含在工程类路径中。例如,一些你依赖的工程可能没有正确的声明它们的依赖集。为了解决这种特殊情况,maven2.x已经引入了显式排除依赖的概念。排除是设置在pom中指定的依赖上,并且有指定的groupId和artifactId来标注。当你构建工程时,该物件不会像解析加载依赖一样被加载到你工程的类路径中。&&&&&& 1. 如何使用排除依赖&&&&&& 我们在pom中的&dependency&段下面加上&exclusions&标签。&project&& ...& &dependencies&&&& &dependency&&&&&& &groupId&sample.ProjectA&/groupId&&&&&& &artifactId&Project-A&/artifactId&& &&&&&version&1.0&/version&&&&&& &scope&compile&/scope&&&&&& &exclusions&&&&&&&& &exclusion& &&!-- declare the exclusion here --&&&&&&&&&& &groupId&sample.ProjectB&/groupId&&&&&&&&&& &artifactId&Project-B&/artifactId&&&&&&& &&/exclusion&&&&&& &/exclusions&&&&&&/dependency&& &/dependencies&&/project&&&&&&& 2.排除依赖是如何工作的并且在何时使用它(作为最后一种解决方法)Project-A&& -& Project-B&&&&&&& -& Project-D &! -- This dependency should be excluded --&&&&&&&&&&&&&& -& Project-E&&&&&&&&&&&&& -& Project-F&& -& Project C&&&&&& 如上图所示,Project-A依赖Project-B和C,Project-B依赖Project-D,Project-D依赖Project-E和F,默认的Project-A的类路径会包含:B, C, D, E, F&&&&&& 如果由于我们知道Project-D的某些依赖在仓库中丢失,那么我们不想Project-D和它所有的依赖加载到Project-A的类路径中,而且也不想/不需要依赖Project-D的Project-B的功能。在这种情况下,Project-B的开发者会提供一个Project-D的 &optional&true&/optional&依赖,如下:&dependency&& &groupId&sample.ProjectD&/groupId&& &artifactId&ProjectD&/artifactId&& &version&1.0-SNAPSHOT&/version&& &optional&true&/optional&&/dependency&&&&&& 然而,并不能达到你想要的效果。作为最后一种解决方法你仍然可以选择将它在Project-A中排除掉。如下:&project&& &modelVersion&4.0.0&/modelVersion&& &groupId&sample.ProjectA&/groupId&& &artifactId&Project-A&/artifactId&& &version&1.0-SNAPSHOT&/version&& &packaging&jar&/packaging&& ...& &dependencies&&&& &dependency&&&&&& &groupId&sample.ProjectB&/groupId&&&&&& &artifactId&Project-B&/artifactId&&&&&& &version&1.0-SNAPSHOT&/version&&&&&& &exclusions&&&&&&&& &exclusion&&&&&&&&&& &groupId&sample.ProjectD&/groupId& &!-- Exclude Project-D from Project-B --&&&&&&&&&& &artifactId&Project-D&/artifactId&&&&&&&& &/exclusion&&&&&& &/exclusions&&&& &/dependency&& &/dependencies&&/project&&&&&& 如果我们将Project-A部署到一个仓库中,而且Project-X声明了一个普通依赖到Project-A。那么Project-D是不是依旧从类路径中排除了?Project-X -& Project-A&&&&&& 答案是yes。Project-A已经声明了它不需要Project-D,所以它不会作为Project-A的传递依赖而引入。那么考虑下图的Project-X依赖Project-Y,Project-X -& Project-Y&&&&&&&&&&&&&& -& Project-B&&&&&&&&&&&&&&&&&&& -& Project-D&&&&&&&&&&&&&&&&&&&&&& ...&&&&&& Project-Y依赖于Project-B,并且它有需要Project-D所支持的功能,所以不能在Project-D的依赖列表中声明排除。也可再提供一个额外的我们可以解析Project-E的仓库。在这种情况下,不能将Project-D全局排除,因为它是Project-Y的合法依赖。&&&&& 在另外一种场景中,如果我们不需要的依赖是Project-E而不是Project-D,我们如何排除它呢?如下图:Project-A&& -& Project-B&&&&&&& -& Project-D&&&&&&&&&&&&&&-& Project-E &!-- Exclude this dependency --&&&&&&&&&&&&&& -& Project-F&& -& Project C&&&&& 排除会影响到在依赖图上所有它的声明点以后的部分。如果你想排除Project-E而不是Project-D,可以简单的将排除指向Project-E。但是你无法将排除作用到Project-D,因为你无法改变Project-D的pom,如果你想这样,你应该用选择依赖而不是排除,或者将Project-D分成多个子工程,每个只有普通依赖。&project&& &modelVersion&4.0.0&/modelVersion&& &groupId&sample.ProjectA&/groupId&& &artifactId&Project-A&/artifactId&& &version&1.0-SNAPSHOT&/version&& &packaging&jar&/packaging&& ...& &dependencies&&&& &dependency&&&&&& &groupId&sample.ProjectB&/groupId&&&&&& &artifactId&Project-B&/artifactId&&&&&& &version&1.0-SNAPSHOT&/version&&&&&& &exclusions&&&&&&&& &exclusion&&&&&&&&&& &groupId&sample.ProjectE&/groupId& &!-- Exclude Project-E from Project-B --&&&&&&&&&& &artifactId&Project-E&/artifactId&&&&&&&& &/exclusion&&&&&& &/exclusions&&&& &/dependency&& &/dependencie&&&&&& 3.为什么排除是依赖的基本概念,而不是在pom层上?&&&&&& 这主要是为了确保依赖图是可预测的,并且防止排除不该排除的依赖。如果你用到了这个最终的解决方法并且必须要把它放到排除中,你必须绝对清楚你讨厌的传递依赖中有哪些依赖会被引入。
阅读(2024) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。&来源于:/p/0fb5e3fb704d
maven至今还是Java编程语言构建的事实标准,大部分项目还在使用maven来进行构建,因此了解maven内部运行的原理对定位和分析问题还是很有裨益的。本篇文章主要介绍一些maven内部运行过程中的一些基本概念,相信看完后,对那么些刚刚接触maven的读者来说maven将不再陌生。&&在具体分析项目构建的过程前,需要了解maven的一些基本概念,这些概念十分重要,请务必理解清楚后再看下文。基本概念主要有:POM,Lifecycle。这两个概念又会包含一些小的概念,下文会逐步讲解。&&POM: 注意这里的POM不是maven中构建过程使用的配置文件pom.xml,但他们之间还是有联系的。POM的全称是Project Object Model,用通俗点的话说就是对要构建的项目进行建模,将要构建的项目看成是一个对象(Object),后文就使用PO来指代这个对象。既然是一个对象,那么PO有哪些属性呢?在maven中一个项目都是用一个唯一的坐标(coordinate)来表示,坐标由groupId, artifactId, version, classifier, type这五部分组成。这样来说PO应该也要具备坐标属性。另外一方面,一个项目肯定不是孤立存在的,可能依赖于其他的一些项目,那么也就是说PO应该具备dependencies这个属性,用来表示其所依赖的外部项目。我们可以尝试一下用Java代码来描述下PO这个对象:
private String groupId;
private String artifactId;
private Set&PO&
&&我们知道XML的表达能力是很强大的,一个Java中的对象是可以用XML来描述,例如一个上面定义的PO对象则可以用下面的XML来描述(表达有不规范之处,理解其中的含义即可):
是不是好像和什么有点类似?对,就是pom.xml。pom.xml就是PO对象的XML描述。上面的PO定义还不完整,我们继续看下PO还有什么其他的属性。我们知道在Java中类是可以继承的,一个对象在创建的时候会同时创建其父类对象,类似的,PO对象也有其父对象,用parent属性来表示,并且PO对象会继承其父对象的所有属性。另外一方面,一个项目可能根据不同职责分为多个模块(module),所有模块其实也就是一个单独的项目,只不过这些项目会使用其父对象的一些属性来进行构建。我们将这些新的属性加到PO的定义中去:
private String groupId;
private String artifactId;
private String
private Set&PO&
private PO
private Set&PO&
再将这个定义用XML语言表示一下:
是不是越来越像pom.xml了?对,这就是pom.xml的由来。再说一遍:pom.xml就是PO对象的XML描述。到此为止,相信你再看pom.xml文件时,会有一个全新的认识。
&&上面说的这些PO属性是项目的一些固有属性,到目前为止,我们还没有涉及项目的构建过程。构建过程对应的是PO对象的build属性,那么你应该马上想到,在pom.xml中就是&build&元素中的内容。这里就有引入maven中第二个核心概念:Lifecycle。Lifecycle直译过来就是生命周期。我们平常会接触到哪些周期呢?一年中春夏秋冬就是一个周期。一个周期中可能分为多个阶段,比如这里的春夏秋冬。在maven中一个构建过程就对应一个Lifecycle,这个Lifecycle也分为多个阶段,每个阶段叫做phase。你可能会问,那这个Lifecycle中包含多少个phase呢?一个标准的构建Lifecycle包含了如下的phase:
validate: 用于验证项目的有效性和其项目所需要的内容是否具备
initialize:初始化操作,比如创建一些构建所需要的目录等。
generate-sources:用于生成一些源代码,这些源代码在compile phase中需要使用到
process-sources:对源代码进行一些操作,例如过滤一些源代码
generate-resources:生成资源文件(这些文件将被包含在最后的输入文件中)
process-resources:对资源文件进行处理
compile:对源代码进行编译
process-classes:对编译生成的文件进行处理
generate-test-sources:生成测试用的源代码
process-test-sources:对生成的测试源代码进行处理
generate-test-resources:生成测试用的资源文件
process-test-resources:对测试用的资源文件进行处理
test-compile:对测试用的源代码进行编译
process-test-classes:对测试源代码编译后的文件进行处理
test:进行单元测试
prepare-package:打包前置操作
package:打包
pre-integration-test:集成测试前置操作
integration-test:集成测试
post-integration-test:集成测试后置操作
install:将打包产物安装到本地maven仓库
deploy:将打包产物安装到远程仓库
&&在maven中,你执行任何一个phase时,maven会将其之前的phase都执行。例如 mvn install,那么maven会将deploy之外的所有phase按照他们出现的顺序一次执行。&&Lifecycle还牵涉到另外一个非常重要的概念:goal。注意上面Lifecycle的定义,也就是说maven为程序的构建定义了一套规范流程:第一步需要validate,第二步需要initialize... ... compile,test,package,... ... install,deploy,但是并没有定义每一个phase具体应该如何操作。这里的phase的作用有点类似于Java语言中的接口,只协商了一个契约,但并没有定义具体的动作。比如说compile这个phase定义了在构建流程中需要经过编译这个阶段,但没有定义应该怎么编译(编译的输入是什么?用什么编译javac/gcc?)。这里具体的动作就是由goal来定义,一个goal在maven中就是一个Mojo(Maven old java object)。Mojo抽象类中定义了一个execute()方法,一个goal的具体动作就是在execute()方法中实现。实现的Mojo类应该放在哪里呢?答案是maven plugin里,所谓的plugin其实也就是一个maven项目,只不过这个项目会引用maven的一些API,plugin项目也具备maven坐标。&&在执行具体的构建时,我们需要为lifecycle的每个phase都绑定一个goal,这样才能够在每个步骤执行一些具体的动作。比如在lifecycle中有个compile phase规定了构建的流程需要经过编译这个步骤,而maven-compile-plugin这个plugin有个compile goal就是用javac来将源文件编译为class文件的,我们需要做的就是将compile这个phase和maven-compile-plugin中的compile这个goal进行绑定,这样就可以实现Java源代码的编译了。有点绕,多看几遍。那么有人就会问,在哪里绑定呢?答案是在pom.xml&build&元素中配置即可。例如:
就将maven-myquery-plugin中的query这个goal绑定到了test这个phase,后续在maven执行到test phase时就会执行query goal。还有有人可能会问,我都没有指定Java源文件的位置,编译啥?这就引出了maven的design principle。在maven中,有一个非常著名的principle就是convention over configuration(约定优于配置)。这一点和ant有非常大的区别,例如使用ant来进行编译时,我们需要指定源文件的位置,输出文件的位置,javac的位置,classpath... ...在maven中这些都是不需要,若没有手动配置,maven默认从&项目根目录&/src/main/java这个目录去查找Java源文件,编译后的class文件会保存在&项目根目录&/target/classes目录。在maven中,所有的PO都有一个根对象,就是Super POM。Super POM中定义了所有的默认的配置项。Super POM对应的pom.xml文件可以在maven安装目录下lib/maven-model-builder-3.0.3.jar:org/apache/maven/model/pom-4.0.0.xml中找到。用一张图来表示maven Lifecycle,phase,goal之间的关系:
Lifecyle-phase-plugin-goal关系图
到此为止,相信对于POM, pom.xml,Lifecycle, phase, goal这些概念应该十分清楚了。
阅读(...) 评论()

我要回帖

更多关于 idea如何使用maven 的文章

 

随机推荐