最初用maven 的最大好处,可以自动打包,自动构建,可以帮我们管理jar包,不用同之前一样手动去找到jar包,copy进去,
但是用着用着发现,maven大多数依赖中都会封装了其他依赖,在一个复杂的项目中,会出现各种依赖冲突。
那么怎么解决这些依赖冲突呢,怎么在多moudle中只添加需要导入父pom中的依赖呢?
先了解下maven构建
将.java .jsp ,第三方jar包,各种配置文件等进行编译,部署,最终变成一个 我们可以直接运行的项目。
构建工程
1.clean:清除之前编译的文件例如.class文件(直接将target文件夹删除 编译的文件,打的包,都存放在target下)
2.compile:将.java,.jsp等文件编译为.class文件,将配置文件按照规定格进行编译。
3.test:这里指的是自动测试(不是junit那种),eg.当我们编译后,确保某些代码正确,就由maven代替我们自动测试,是否正确
4.报告:这里据说是 test之后生产的测试报告。
5.package:将一个工程下的多个文件,打成一个包,普通java工程 jar包,web 工程 war包。便于安装或部署
6.install:将打好的包 下载到本地仓库,这样可以被其他工程引用
7.deploy:将web工程 打成的war包 发到指定的servlet目录下 使其可以运行。
①target编译结构
classes就是正常编译的
test-classes 就是测试的.class文件
下面的Jar包 就是package是生成的
clean 就是把target清空了
编译目录结构
②坐标
相当于一个标识 可以找到对应的位置
<groupId>mysql</groupId> //公司名称
<artifactId>mysql-connector-java</artifactId> //项目名称
<version>5.1.36</version> //版本号
意思是mysql 公司 mysql-connector-java这个项目 版本为5.1.36
③仓库
仓库主要分为本地仓库和远程仓库
本地:我们当前电脑中的仓库
远程:私有仓库和中央仓库
maven获取jar包,war包等流程图。
流程
④依赖
dependency 根据坐标去找,流程如上图。
若我们自己的包,package之后 要install 下载的本地仓库,不然找不到
4.1依赖范围
大体有4个条件决定
1.对主程序是否有效
2.对测试程序是否有效
3.是否参与打包
4.是否参与部署
常见3个 | compile | test | provided |
---|---|---|---|
对主程序是否有效 | 是 | 否 | 是 |
对测试程序是否有效 | 是 | 是 | 是 |
是否参与打包 | 是 | 否 | 否 |
是否参与部署 | 是 | 否 | 否 |
例子 | junit | servlet-api |
provided适用于 在本机上运行测试都可以,当要部署到服务器上时,例如tomcat,本机编译测试时,要有servlet-api.jar,而部署服务器上有servlet-api相关环境,就不需要打包部署了。
⑤生命周期
构建时的执行过程和顺序。
maven是由插件来完成打包,编译等操作。
他是按照某一特定的执行顺序来进行。
例如compile:
package:
可以看到他都是有特定的顺序 先compile 在testResources 一步一步来是一个组合的过程(执行这一操作,包含前面其他操作)
⑥依赖(高级)
6.1依赖的传递性
image.png
可以看到我们要导入spring-test这个jar时 spring-test 依赖spring-core,spring-core依赖spring-jcl。所以都会导入进来。
好处:我们只需要在 最"下"层的module加 不必每个moudle都加
PS:只有compile范围的依赖才可以传递,所以别的module如果需要,需手动添加(一般这些比较少,不会出现过多冗余)
6.2依赖的排除
假设某个jar包不稳定或者冲突时,我们需要排除这个jar
image.png
eg.我们排除画X的依赖
6.3依赖原则
(1)路径最短优先选择
假如有3个moudle A-->B-->C
B有log4j.1.2.1
C有log4j.1.2.4
根据依赖的传递性A也会有log4j 但是版本是哪个呢 B,因为B路径最短。(当然我们也可以手动申明需要哪个版本)
(2)路径相同时 先申明者优先
如果3个moduleA--B,C
B有log4j.1.2.1
C有log4j.1.2.4
A同时依赖两个
同样根据依赖的传递性A也会有log4j
此时看A的pom中 他先应用哪个moudle的依赖就用谁的版本(当然我们也可以手动申明需要哪个版本)
6.4统一管理所需的jar包的版本
当我们各个module中jar包版本不一致,容易冲突,所以我们用properties标签管理起来,这样即解决了冲突,又方便了修改(这里适用于多个moudle,最后借助一个父module 全部依赖放到父pom.xml 后面会讲到)
image.png
6.5继承
例如junit scope为test 根据依赖的传递性,test不能被传递,所以其他moudle就可能出现版本不一致问题,团队协同开发不方便。
所以用一个父pom管理 打包方式为pom
子pom.xml 中配置如下图,这样子module就会去找到父模块中<dependencyManagement>的标签去引用他的版本号
PS:<dependencyManagement>中定义的只是依赖的声明,并不实现引入,子项目中申明时才会引入
<parent>
<artifactId>cloud-project</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
<!-- 以当前工程所在位置去找 父工程的pom.xml 相对路径-->
<relativePath>../pom.xml</relativePath>
</parent>
子moudle无需指定版本号
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
6.6聚合
在多module中 moduleA依赖moudleB ,moudleB依赖moudleC
如果我们PackageA 时 必须先B ok ,B必须C ok,所以我们需要手动去按C,B最后在A,按顺序来。ps:继承中也要先install parent moudle
而添加了 如下<Modules>标签以后,maven会自动帮我门找到依赖关系,自动安装
<modules>
//module里写相对路径,(在父moudle下建立的子module也可以通过moudle名找到)
<module>eureka-server7001</module>
<module>common-api</module>
</modules>
pom打包是什么意思?
pom打包不同与jar,war包 对于编译后具体的资源进行打包,
他只在父级工程或聚合工程中 作为jar包的版本控制,作为其他项目的依赖
package,install,deploy区别
package 进行了项目编译,单测,打包。
install 进行了项目编译,单测,打包,并且把包下载到了本地仓库。
deploy 进行了项目编译,单测,打包,并且把包下载到了本地仓库和私有仓库。
网友评论