maven帮助构建项目 项目和项目之间的依赖关系,管理jar包。
项目管理工具,管理java项目:
1、项目对象模型
POM对象模型,每个maven工程中都有一个pom.xml文件,定义工程所依赖的jar包、本工程的坐标、打包运行方式。。
2、依赖管理系统(基础核心 )
maven通过坐标对项目工程所依赖的jar包统一规范管理。
3、maven定义一套项目生命周期
清理、初始化、编译、测试、报告 、打包、部署、站点生成
maven的坐标
groupId:是项目组织唯一的标识符,比如com.ziyun
artficatId:是项目的唯一的标识符,实际对应项目的名称,比如service-pay
Version:项目的版本
maven工程的打包方式
Jar:
存放一些其他工程都会使用的类,工具类。我们可以在其他工程的pom文件中去引用它,和引用别的jar包没什么区别。
Pom:
父项目,用在父级工程或聚合工程中。用来做jar包的版本控制。
War:
web项目的打包方式,需要部署在服务器上的项目这些工程有的是用户通过浏览器直接访问,有的是通过发布服务被别的工程调用。
mavne找jar包的两个网站地址
常见命令
maven通过命令对工程进行清理(clean)、编译(compile)、测试(test)、打包(package)、部署(install)。
每一大生命周期执行某一步骤的时候,之前的步骤都会执行,后面的阶段是依赖于前面的阶段的..
常用命令如下:
compile:编译
clean:清理,将target下的class文件清理
test: 执行单元测试类,执行src/test/java下的类
package :将java工程打成jar、war。
install:安装命令,将工程的jar发布到本地仓库
发布到仓库,目录按照本工程定义的坐标生成目录
聚合与继承
(一)聚合(开发的主要方式)
我们的分层架构、分模块开发,来提高代码的清晰和重用。针对于这一特性,maven也给予了相应的配置。
所谓聚合,顾名思义,就是把多个模块或项目聚合到一起,我们可以建立一个专门负责聚合工作的Maven 工程。
建立该project的时候,我们要注意以下几点:
1.聚合模块本身也做为一个Maven项目,它必须有自己的POM
2.打包方式: pom
3.引入了新的元素:modules---module
4.版本:聚合模块的版本和被聚合模块版本一致
5.相对目录:每个module的值都是一个当前POM的相对目录
6.目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致,总之,模块所处的目录必须和<module>模块所处的目录</module>相一致。
7.习惯约定:为了方便构建,通常将聚合模块放在项目目录层的最顶层,其它聚合模块作为子目录存在。
8.聚合模块减少的内容:聚合模块的内容主要是一个pom.xml文件,它不包含src/main/Java、src/test/java等目录,因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。
9.聚合模块和子模块的目录:
他们可以是父子类,也可以是平行结构,当然如果使用平行结构,那么聚合模块的POM也需要做出相应的更改。
父工程聚合多个项目,多个项目是是一个整体,只需要编译运行父工程
(二)继承
我们在项目开发的过程中,可能多个模块独立开发,但是多个模块可能依赖相同的元素,这时我们采用继承,就不用在每个子模块分别定义了。
如何配置继承:
1.说到继承肯定是一个父子结构,那么我们在父工程中来创建一个parent project
2.<packaging>: 作为父模块的POM,其打包类型也必须为POM
3.结构:父模块只是为了帮助我们消除重复,所以它也不需要src/main/java、src/test/java等目录
4.新的元素:<parent> , 它是被用在子模块中的
5.<parent>元素的属性:<relativePath>: 表示父模块POM的相对路径,在构建的时候,Maven会先根据relativePath检查父POM,如果找不到,再从本地仓库查找
6.relativePath的默认值: ../pom.xml
7.子模块省略groupId和version: 使用了继承的子模块中可以不声明groupId和version。
(三)聚合与继承的区别
聚合:把多个模块或项目聚合到一起,我们可以建立一个专门负责聚合工作的 Maven 工程。 modules---module
继承:是指明某个模块工程要继承另一个模块功能。解决多个模块依赖相同的元素,,消除重复 ,, 模块之间是父子关系
父工程做版本控制:子模块(工程)继承父工程,只需要在父工程写依赖,所有的子工程的jar包的版本保持一致,也消除重复,通过父项目引入jar包..
有聚合不一定有继承,,有继承一定有聚合.. https://www.jianshu.com/p/d70e2164ddbd
聚合和继承通常是结合使用的,但是其作用是不同的。聚合是将多个模块的工程汇聚到一起,而继承则是指明某个模块工程要继承另一个模块功能。
父工程聚合多个项目,多个项目是是一个整体,只需要编译运行父工程
构建多模块Maven工程(重点)
Maven多模块项目,适用于一些比较大的项目,通过合理的模块拆分,实现代码的复用,便于维护和管理。尤其是一些开源框架,也是采用多模块的方式,提供插件集成,用户可以根据需要配置指定的模块。
拆分规则:
(1)按业务模块拆分
- 按层拆分
创建Maven父工程(erp_parent)
-
构建完各个模块后,会发现父工程的pom.xml中自动出现如下信息:
<modules> <module>erp_domain</module> <module>erp_dao</module> <module>erp_service</module> <module>erp_web</module> </modules>
这部分的配置信息是父工程聚合子模块的信息
而子模块的pom.xml内容如下:
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.itcast.erp</groupId> <artifactId>erp_parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>erp_domain</artifactId> </project>
建立Maven子模块之间的依赖
各模块的依赖关系如下:
erp_dao 依赖erp_domain
erp_service 依赖erp_dao
erp_web依赖erp_service
我们现在建立erp_dao和erp_domain的依赖:
工程右键 Maven --> Add Dependency
七、依赖管理
(一)依赖范围
依赖范围是用来控制依赖与3种classpath(编译classpath,测试classpath,运行classpath)的关系。maven有以下几种依赖范围:
1、compile : 编译、测试、运行,A在编译时依赖B,并且在测试和运行时也依赖。
打到war包或jar包。
2、provided: 编译、和测试有效,A在编译和测试时需要B。
比如:servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)。
不会打到war。
3、runtime:测试、运行有效。
比如:jdbc驱动包 ,在开发代码中针对java的jdbc接口开发,编译不用。
在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库,需要的!!
会打到war。
4、test:只是测试有效,只在单元测试类中用。
比如:junit
不会打到war。
如何设置依赖范围呢?
比如我们要将mysql驱动的依赖设置为runtime范围,配置如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
将servlet依赖设置为provided
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
如果是compile就不需要设置了,因为compile是scope的默认值。
(二)依赖传递
什么是依赖传递?
A->B(compile) 第一关系: a依赖b compile
B->C(compile) 第二关系: b依赖c compile
我们看下图:
1、纵坐标:直接依赖
A依赖B,B是A的直接依赖。
在A的pom.xml中添加B的坐标。
2、横坐标:传递依赖
B依赖C,C是A的传递依赖。
3、中间部分:传递依赖的范围,A依赖C的范围。
(三)依赖调节原则(了解)
情景再现:
项目A依赖于项目B,项目B依赖于项目C(v1), 项目A依赖于项目D,项目D依赖于项目E,项目E依赖于C(v2),
1、A--->B---->C(v1) ,
2、A------>D---->E----->C(v2)
项目A隐形依赖了两个版本的C,那到底采用哪个版本呢?
分析:
依赖调解第一原则:路径优先,很明显,第一种路径深度是3,第二种路径深度是4,所以,maven会采用C(v1)
依赖调解第二原则:声明优先,假设路径深度相等,那么声明在前的会被引用。
(四)版本锁定
在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。
pom.xml文件中,jar的版本判断的两种途径
1.如果dependencies里的dependency自己没有声明version元素,那么maven就会倒dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version。
2.如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。
(五)排除依赖
如果这两个jar包同时存在,会导致后续某些操作会存在问题(比如openSessionInView失效),所以需要排除低版本的jar包。
如何来排除依赖呢?添加下面红色字体的部分。作用是排除struts中依赖的javassist的jar
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.24</version>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>