4.1. Maven坐标 GAV
在简单平面几何中坐标(x,y)可以标识平面中唯一的一点。
在项目开发中,Maven坐标就是为了定位一个唯一确定的jar包。
我们经常用到的一些开源框架,他们的名称和版本号以及版本的类型就确定了他们的唯一性,我们引用这些开源框架时,就可以通过坐标来指定他们。
Maven坐标简称GAV
-
groupId: 代表当前项目组织名称
-
artifactId:代表当前项目名称
-
version:代表当前项目的当前版本
如下图所示,我们通过GAV坐标就能指定引用junit这个项目以及它的具体版本:
4.2. Maven依赖管理
Maven的依赖管理,主要就是在pom.xml文件中定义的项目中需要引用的jar包,其中包括依赖的jar包的GAV坐标,依赖的一些特性。
以引用junit测试的jar包为例,pom.xml引用此jar包的格式为:
4.2.1. 依赖范围 scope属性
scope 属性我们需要了解其中的四种:compile / test / perovided / runtime。
-
compile:编译依赖范围,scope属性的默认值,表示在编译,测试,系统运行时 都需要此jar包,比如:log4j.jar。
-
test:测试依赖范围表示只是在测试的过程中需要用到此jar包,比如:junit.jar。
-
provided:已提供依赖范围,表示在编译,测试时需要用到此jar包,但是在正 式的运行环境中,不需要此jar包,因为运行的容器已经提供,比如:servlet-api.jar。
-
runtime:运行时依赖范围,表示只在运行需要用到此jar包,比如:数据库驱 动的jar包。
4.2.2. 依赖传递
4.2.2.1. 直接依赖和间接依赖
以maven01项目和maven02项目为例,当maven02项目依赖maven01项目中,我们称maven02直接依赖maven01项目,同理maven01项目也直接依赖于log4j.jar,而maven02对于或者log4j.jar来说,是间接依赖的关系。
注意:依赖范围在传递依赖时会略有变化。
-
当第二直接依赖的范围是compile的时候(log4j.jar),依赖会向下传递;
-
当第二直接依赖的范围是test的时候,依赖不会得以传递(junit.jar);
-
当第二直接依赖的范围是provided的时候,依赖不会向下传递(servlet.jar);
-
当第二直接依赖的范围是runtime的时候,依赖会向下传递(mysql.jar);
4.2.3. 依赖冲突
-
如下图所示,当一个项目中依赖同一个项目,但是不同的版本的情况下,以在配置文件中的位置最下方的版本为准(就近原则)
-
如下图所示,如果直接与间接依赖中包含有同一项目但是不同版本的资源依赖,以直接依赖的版本为准:
总结:当存在依赖冲突时,以就近原则来解决此类问题(同项目,以配置文件最下面为准/依赖传递就近以直接依赖为准)。
4.2.4. 可选依赖
如下图所示,我们指定某个jar包的依赖时,还有个 optional 属性,默认值为 false,如果值为 true,则代表这个被引用的 jar 是可选依赖,不能往下传递。
如上图:当我们添加optional属性为true时,maven02虽然依赖maven01项目,但是mave01项目引用的spring-context项目并没有传递给maven02项目。
4.2.5. 排除依赖
如下图所示:如果maven02项目依赖maven01项目,但是maven01项目引用的一些jar包,maven02项目不需要,这个时候,可以配置exclusions标签进行排除,这就是排除依赖
4.3. Maven生命周期
4.3.1. 生命周期概念
Maven生命周期就是项目构建的所有步骤。
Maven对项目构建所有的步骤进行了抽象和统一。包括项目清理、初始化、编译、打包、测试、部署等几乎所有构建步骤。
Maven中有三套相互独立的生命周期:
-
Clean Lifecycle: 在进行真正的构建之前进行一些清理工作。
-
Default Lifecycle: 构建的核心部分,编译,测试,打包,部署等等。
-
Site Lifecycle: 生成项目报告,站点,发布站点。
注意:它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。
4.3.2. clean:清理项目
clean生命周期一共包含了三个阶段:
-
pre-clean 执行一些需要在clean之前完成的工作
-
clean 移除所有上一次构建生成的文件
-
post-clean 执行一些需要在clean之后立刻完成的工作
注意:我们在上面的章节运行的mvn clean 执行 等同于mvn pre-clean clean 两个指令的叠加,这是Maven很重要的一个规则,可以大大简化命令行的输入。
4.3.3. default:构建项目
Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。整个周期如下:
- validate
- generate-sources
- 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 接受编译好的代码,打包成可发布的格式,如 JAR 。
- pre-integration-test
- integration-test
- post-integration-test
- verify
- **install 将包安装至本地仓库,以让其它项目依赖。 **
- **deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。 **
4.3.4. site:生成项目站点(了解)
Site生命周期主要用来生成和发布maven站点 ,开发人员很少用到,有特殊要求的项目经理可以通过它来自动生成文档和统计数据,主要阶段如下:
-
pre-site 执行一些需要在生成站点文档之前完成的工作
-
site 生成项目的站点文档
-
post-site 执行需要在生成站点文档之后完成的工作,并且为部署做准备
-
site-deploy 将生成的站点文档部署到特定的服务器上
4.4. Maven插件
Maven仅仅定义了抽象的生命周期,具体的任务都是交由对应的插件完成的。每个插件都能实现一个生命周期里面的过程。Maven的生命周期与插件目标相互绑定,以完成某个具体的任务。
比如:compile就是插件maven-compiler-plugin的一个插件目标。
4.4.1. Maven编译插件
当我们需要指定某个项目以什么JDK的版本进行编译时,可以在pom.xml文件上指定JDK版本。
注意:修改配置文件后,需要右击工程 选择maven→update project configration。
4.4.2. WEB容器插件(Tomcat)
4.4.2.1. 使用maven创建一个web工程
第一步:不选用骨架。
第二步:将打包方式选择为war。
第三步:点击finish,工程创建成功。
第四步:在工程中添加web.xml。
第五步:在webapp下创建index.jsp。
第六步:在pom.xml文件里面引入servlet-api.jar。
4.4.2.2. 运行tomcat插件
tomcat:run 运行tomcat6(默认)版本太低,不建议
tomcat7:run 运行tomcat7(推荐,但是需要添加插件)
也可以直接用外部tomcat直接运行:
4.5. Maven父子继承
通过上面maven依赖管理的学习,我们可以知道,maven工程之间的依赖关系是可以传递的。
通过依赖关系的传递,我们可以将不同项目中间相同的配置提取出来,放到统一放到一个父工程,然后其他工程作为子工程继承父工程的一些公用配置。
4.5.1. 创建父工程
4.5.2. 创建子工程
创建方式有两种:
一种是创建新工程为子工程,在创建时设置父工程的GAV。
一种是修改原有的工程为子工程,在子工程的pom.xml文件中手动添加父工程的GAV。
现有工程继承父工程只需要在pom文件中添加parent节点即可。
4.5.3. 父工程统一依赖jar包
在父工程中对jar包进行依赖,在子工程中都会继承此依赖。
4.5.4. 父工程统一管理版本号
Maven使用dependencyManagement管理依赖的版本号。
注意:此处只是定义依赖jar包的版本号,并不实际依赖。如果子工程中需要依赖jar包还需要添加dependency节点。
4.5.5. 父工程中版本号提取
当父工程中定义的jar包越来越多,找起来越来越麻烦,所以可以把版本号提取成一个属性集中管理。
4.6. Maven聚合工程
聚合一般是一个工程拆分成多个模块工程进行开发,每个模块是一个独立的工程,但是要是运行时必须把所有模块聚合到一起才是一个完整的工程,此时可以使用maven的聚合工程。
比如:按功能模块划分(framework模块/系统管理/各个业务模块/)可以对不同的模块单独创建工程,最终在打包时,将不同的模块聚合到一起。
比如: 按MVC开发模式划分 ,将controller /service/dao按照分层创建不同的工程,最终在打包时,将不同的模块聚合到一起。
4.6.1. 创建一个聚合工程
聚合工程的打包方式必须是pom,一般聚合工程和父工程合并为一个工程。
4.6.2. 创建持久层工程
第一步:在maven-web工程上,点击new –> project。
第二步:next。
4.6.3. 创建业务层工程
同理,根据上面过程建立业务逻辑处理(Service)工程。
4.6.4. 创建controller工程
注意:controller是个javaWeb项目。
点击next,进行下面的页面
修改web.xml和index.jsp 引入servlet-api
聚合之后的maven-web工程的pom文件内容如下:
4.6.5. 运行聚合工程
在主工程pom.xml文件中指定tomcat运行插件
Run as Tomcat7:run