用了maven两三年了,都是拿过来直接用的,今天来细细讲解一下maven的各种参数:
Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具,简单的说就是用来管理项目所需要的依赖且管理项目构建的工具。
Maven 官网:https://maven.apache.org
maven把项目的构建划分为不同的生命周期(lifecycle)。包括:
maven使用如下几个要素来唯一定位某一个输出物:
groupId;artifactId;packaging;version。
maven在版本管理时候可以使用几个特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:
1. SNAPSHOT 如果一个版本包含字符串"SNAPSHOT",Maven就会在安装或发布这个组件的时候将该符号展开为一个日期和时间值,转换为UTC时间。例如,"1.0-SNAPSHOT"会在2010年5月5日下午2点10分发布时候变成1.0-20100505-141000-1。这个词只能用于开发过程中,因为一般来说,项目组都会频繁发布一些版本,最后实际发布的时候,会在这些snapshot版本中寻找一个稳定的,用于正式发布,比如1.4版本发布之前,就会有一系列的1.4-SNAPSHOT,而实际发布的1.4,也是从中拿出来的一个稳定版。
2.LATEST 指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
3.RELEASE 指最后一个发布版
项目结构图:
parent
├─childA(model层)
│ └─pom.xml(jar)
├─childB(web层)
│ └─pom.xml(war)
└─pom.xml(pom)
com.ht
parent
1.0-SNAPSHOT
pom
childA
childB
childA和childB的pom.xml都需要配置parent,防止引入的包冲突(如果不加parent,会分别去编译他们引入的依赖,会重复引入包):
parent
com.ht
1.0-SNAPSHOT
4.0.0
childA
jar
parent
com.ht
1.0-SNAPSHOT
4.0.0
childB
war
com.module
childA
1.0-SNAPSHOT
parent中加上dependencyManagement,child项目就可以继承parent项目的依赖,并且在child中可以不用加version了。
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
子项目直接引入parent就行
dependency依赖关系中Scope(范围)的作用:主要管理依赖的部署。
如果不显示执行
删除线格式 属性时,默认
。
scope 属性包括(5个值):
1. compile(编译范围):编译范围的在所有的classpath中可用,同时它们也会被打包
2. provided(已提供范围):表示部署的环境当中有某容器已经提供了该jar包,只在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的servlet容器(Tomcat)提供。
3. runtime(运行时范围):只在运行和测试系统的时候需要,但在编译的时候不需要。
4. test(测试范围):在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
5. system (系统范围):该范围不推荐使用(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)
详细可参考:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope
maven的依赖关系是有传递性的。如:A–>B,B–>C。但有时候,项目A可能不是必需依赖C,因此需要在项目A中排除对A的依赖。在maven的依赖管理中,有两种方式可以对依赖关系进行,分别是可选依赖(Optional Dependencies)以及依赖排除(Dependency Exclusions)。
当一个项目A依赖另一个项目B时,项目A可能很少一部分功能用到了项目B,此时就可以在A中配置对B的可选依赖。举例来说,一个类似hibernate的项目,它支持对mysql、oracle等各种数据库的支持,但是在引用这个项目时,我们可能只用到其对mysql的支持,此时就可以在这个项目中配置可选依赖。
配置可选依赖的原因:1、节约磁盘、内存等空间;2、避免license许可问题;3、避免类路径问题,等等
。
sample.ProjectB
Project-B
1.0
compile
true
假设以上配置是项目A的配置,即:Project-A --> Project-B。在编译项目A时,是可以正常通过的。
如果有一个新的项目X依赖A,即:Project-X -> Project-A。此时项目X就不会依赖项目B了。如果项目X用到了涉及项目B的功能,那么就需要在pom.xml中重新配置对项目B的依赖。
当一个项目A依赖项目B,而项目B同时依赖项目C,如果项目A中因为各种原因不想引用项目C,在配置项目B的依赖时,可以排除对C的依赖。
示例(假设配置的是A的pom.xml,依赖关系为:A --> B; B --> C):
sample.ProjectB
Project-B
1.0
compile
sample.ProjectC
Project-C
当然,对于多重依赖,配置也很简单,参考如下示例:
项目A–> 项目B --> 项目C --> 项目D --> 项目E
sample.ProjectB
Project-B
1.0-SNAPSHOT
sample.ProjectE
Project-E
dependency中type默认为jar即引入一个特定的jar包。那么为什么还会有type为pom呢?
当我们需要引入很多jar包的时候会导致pom.xml过大,我们可以想到的一种解决方案是定义一个父项目,但是父项目只有一个,也有可能导致父项目的pom.xml文件过大。这个时候我们引进来一个type为pom,意味着我们可以将所有的jar包打包成一个pom,然后我们依赖了pom,即可以下载下来所有依赖的jar包
org.springframework.boot
spring-boot-dependencies
${spring.boot.version}
pom
import
用户可以使用该类属性引用POM文件中对应元素的值。如${project.artifactId}就对应了
元素的值,常用的POM属性包括:
${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/
${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/
${project.build.directory} : 项目构建输出目录,默认为target/
${project.outputDirectory} : 项目主代码编译输出目录,默认为target/classes/
${project.testOutputDirectory}:项目测试主代码输出目录,默认为target/testclasses/
${project.groupId}:项目的groupId
${project.artifactId}:项目的artifactId
p r o j e c t . v e r s i o n : 项 目 的 v e r s i o n , 与 {project.version}:项目的version,与 project.version:项目的version,与{version} 等价
p r o j e c t . b u i l d . f i n a l N a m e : 项 目 打 包 输 出 文 件 的 名 称 , 默 认 为 {project.build.finalName}:项目打包输出文件的名称,默认为 project.build.finalName:项目打包输出文件的名称,默认为{project.artifactId}-${project.version
例子:
UTF-8
2.1.6_RELEASE
1.8
1.8
不配置Plugin时,Maven默认会使用以下插件。如果针对各个 plugin 有特殊配置的话,需要显示指定 plugin 和 属性配置。
其中的build标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过build中配置的 plugin 来完成。当然plugin配置不是必须的,默认情况下,Maven 会绑定以下几个插件来完成基本操作。
plugin | function | life cycle phase |
---|---|---|
maven-clean-plugin | 清理上一次执行创建的target文件 | clean |
maven-resources-plugin | 处理资源文件 | resources,testResources |
maven-compiler-plugin | 编译Java代码 | compile、testCompile |
maven-surefire-plugin | 执行单元测试文件 | test |
maven-jar-plugin | 创建 jar | package |
maven-install-plugin | 清理上一次执行创建的target文件拷贝jar到本地的maven仓库 /repository 下面清理上一次执行创建的target文件 | install |
maven-deploy-plugin | 发布 ja | deploy |
maven-site-plugin | 生成文档 | site |
maven-site-plugin:将工程所有文档生成网站,生成的网站界面默认和apache的项目站点类似,但是其文档用doxia格式写的,目前不支持docbook,需要用其他插件配合才能支持。需要指出的是,在maven 2.x系列中和maven3.x的site命令处理是不同的,在旧版本中,用 mvn site 命令可以生成reporting节点中的所有报表,但是在maven3中,reporting过时了,要把这些内容作为 maven-site-plugin的configuration的内容才行。
src/main/java
true
**/*.xml
src/main/resources
true
**/*.properties
*.xml
*.dic
*.txt
src/main/resources
false
*.p12
maven-compiler-plugin
3.1
1.8
UTF-8
org.apache.maven.plugins
maven-resources-plugin
2.6
UTF-8
spring-boot-maven-plugin
当使用SpringBoot开发项目的时候,会使用到spring-boot-maven-plugin插件
Spring Boot Maven plugin有5个Goals:
命令 | 说明 |
---|---|
spring-boot:repackage | 默认goal。在mvn package之后,再次打包可执行的jar/war, 并将mvn package生成的软件包重命名为*.original |
spring-boot:run | 运行Spring Boot应用 |
spring-boot:start | 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理 |
spring-boot:stop | 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理 |
spring-boot:build-info | 生成Actuator使用的构建信息文件build-info.properties |
其中比较重要的命令是:
mvn package spring-boot:repackage
执行后会看到生成的两个jar文件,一个是*.jar,另一个是*.jar.original。
这是由于在执行上述命令的过程中,Maven首先在package阶段打包生成*.jar文件;然后执行spring-boot:repackage重新打包
maven-source-plugin提供项目自动将源码打包并发布的功能,在需要发布源码项目的pom.xml文件中添加如下代码即可:
org.apache.maven.plugins
maven-source-plugin
attach-sources
jar
执行 mvn install
,maven会自动将source install到repository 。
执行 mvn deploy
,maven会自动将source deploy到remote-repository 。
执行 mvn source:jar
,单独打包源码。
注意:在多项目构建中,将source-plugin置于顶层或parent的pom中并不会发挥作用,必须置于具体项目的pom中。
至此,参数不全,后续再补!