在目前流行的SSM,SSH都采用Maven作为项目构建工具,所以有必要 基于《Maven权威指南》 进行一次较系统的学习。
1、介绍Apache Maven
1.1 Maven较正式定义
Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在 生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。 当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后 Maven 可以应用横切的逻辑, 这些逻辑来自一组共享的(或者自定义的)插件。
1.2 约定大于配置
• Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里。它把字节码放到 target/classes ,然后在 target 生成一个 JAR 文件。
• Maven 是声明式的。你需要做的只是创建一个 pom.xml 文件然后将源代码放到默认的目录。Maven 会帮你处理其它的事情。
• Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告 诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。
2、 项目对象模型(POM)
2.1、我们已经确定了POM是描述性和声明性的,它不像Ant或者Make那样提供显式的指令,我们也注意到POM的概念不是特定于Java的。
2.2、属性引用:一个POM可以通过一对大括弧和前面一个美元符号来包含 对属性的引用 ${app.bu.version}
2.3、依赖范围:项目依赖”简要介绍了三种依赖范围:compile,test,和provided
compile(编译范围) compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范 围。编译范围依赖在所有的classpath中可用,同时它们也会被打包。
provided(已提供范围) provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用。例如,如果 你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编 译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个 Servlet API JAR由你的应用服务器或者servlet容器提供。已提供范围的依赖在 编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。
runtime(运行时范围) runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实 现。
test(测试范围) test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运 行阶段可用
system(系统范围) system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中 JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库 的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它。如 果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用 依赖)。
2.4、依赖版本界限
(, ) 不包含量词 (3.1,3.5)大于3.1小于3.5; (,3.5)小于3.5
[, ] 包含量词 (3.1, 3.5] 大于3.1小于等于3.5; [3.1,] 大于等于3.1
2.5、传递性依赖
你可以只依赖于一些包如Spring Framework,而不 用担心Spring Framework的所有依赖,Maven帮你自动管理了。加上springboot里的jar包集成了很多spring的其他东西,结合maven传递性依赖,自动管理依赖。只有在子项目没有直接声明一个版本的时候,父POM的dependencyManagement定义的版本才会被使用。
2.6、多模块项目关系
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>top-group</artifactId>
...
<modules>
<module>sub-group</module>
<module>project-c</module>
</modules>
...
</project>
--
当Maven读取top-group的POM的时候,它会检查它的modules元素,看到top-group引用了 项目sub-group和project-c。之后Maven会在它们的每个子目录中寻找pom.xml。Maven为 每一个子模块重复这个过程:它会读取sub-group/pom.xml然后看到sub-group项目通过 如下的modules元素引用了两个项目。
2.7、 多模块 vs. 继承:达到重用依赖的目的
继承于一个父项目和被一个多模块项目管理是有区别的。一个父项目是指它把所有的值 传给它的子项目。一个多模块项目只是说它管理一组子模块,或者说一组子项目。多模块关系从上层往下定义。当建立一个多模块项目的时候,你告诉一个项目它的构建需要包含指定的模块。多模块构建用来将模块聚集到一个单独的构建中。父子关系是从叶节点往上定义的。父子关系更多的是处理一个特定项目的定义。当你给一个子项目关联一 个父项目的时候,你告诉Maven该项目的POM起源于另一个项目。
注意:一个项目只能有一个父项目。
3、构建生命周期
3.1 、Maven基于构建生命周期的中心概念。这意味着构建和分发特定工件(项目)的过程被明确定义。对于构建项目的人员,这意味着只需要学习一小堆命令即可构建任何Maven项目,POM将确保他们获得所需的结果。Maven中有三种标准的生命周期:清理(clean),默认(default)(有时候也称为构建),和站点(site)。在默认(default)的生命周期处理你的项目部署,将清洁(clean)的生命周期处理项目的清理,而站点(site)的生命周期处理你的项目站点文档的创建,开源文档会用到。
3.2 3个生命周期的构建阶段都绑定了默认插件,可以在项目中重新定义覆盖(最好就用默认的)。