-
学习目标
资料
简单介绍
Maven仓库
Maven项目构建的过程
依赖冲突,以及解决方案
maven clean install -DskipTests构建过程
Idea,中maven使用,以及插件 maven helper
-
资料
<u>https://maven.apache.org/</u>
<u>https://maven.apache.org/what-is-maven.html</u>
-
简单介绍
是什么:构建和管理任何基于 Java 的项目的工具
好处:简化构建过程、提供统一的构建系统、提供优质的项目信息
maven工程的目录结构
<u>https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html</u>
[图片上传失败...(image-1a4b2-1657791628086)]
说明:
src/main/java —— 存放项目的.java文件
src/main/resources —— 存放项目资源文件,如spring, mybatis,resouse,yml配置文件
src/test/java —— 存放所有单元测试.java文件,如JUnit测试类
src/test/resources —— 测试资源文件
pom.xml——maven项目核心配置文件Project
-
Maven仓库
Maven本地和远程仓库
maven首先会去本地,仓库中去找jar,找不到会到远程仓库去找(公司有仓库会到公司仓库中取下载有关jar包),一般远程中央仓库在国外是无法连接的,我们可以用aliyun的仓库
1、本地仓库
本地仓库的默认路径为用户~/Users/.m2/repository
在用户配置setting.xml中<localRepository>~/Users/.m2/repository</localRepository>字段修改本地仓库的路径
2、远程仓库
如果项目依赖的库在本地仓库中没有找到,maven就会去远程仓库找,maven有默认的远程仓库,就是他的中央仓库
3、镜像仓库
一般默认的远程仓库在国内可能连接不上,所以我们可以修改远程仓库的地址为国内的镜像仓库上
修改maven根目录下的conf文件夹中的setting.xml文件,内容如下:
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
配置文件
maven仓库地址、私服(公司)等配置信息需要在setting.xml文件中配置,分为全局配置和用户配置。
1、全局配置:在maven安装目录下的有 conf/setting.xml文件,此setting.xml文件用于maven的所有project项目,它作为maven的全局配置。
2、用户配置:如需要自己配置,用户配置的setting.xml文件默认的位置在:目录中~/User/.m2/settings.xml中
maven会先找用户配置,如果找到则以用户配置文件为准,否则使用全局配置文件。
-
Maven项目构建过程
1、按指定顺序执行的三个生命周期 clean,default,site
<u>https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#lifecycle-reference</u>
2、构建官方文档部分
<u>https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#</u>
项目构建是一个项目从编写源代码,经过如下过程
这些构建生命周期中的每一个都由不同的构建阶段列表定义,其中构建阶段代表生命周期中的一个阶段。
例如,默认生命周期包含以下阶段
validate - 验证项目是否正确并且所有必要的信息都可用
compile - 编译项目的源代码
test- 使用合适的单元测试框架测试编译的源代码。这些测试不需要代码被打包或部署
package - 获取已编译的代码并将其打包成可分发的格式,例如 JAR。
verify - 对集成测试的结果进行任何检查,以确保满足质量标准
install - 将包安装到本地存储库中,作为本地其他项目的依赖项
deploy - 在构建环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享。
这些生命周期阶段(以及此处未显示的其他生命周期阶段)按顺序执行以完成default生命周期。鉴于上述生命周期阶段,这意味着当使用默认生命周期时,Maven 将首先验证项目,然后将尝试编译源代码,针对测试运行它们,打包二进制文件(例如 jar),针对该项目运行集成测试包,验证集成测试,将经过验证的包安装到本地存储库,然后将安装的包部署到远程存储库。
3、构建过程依赖插件来完成
-
依赖冲突以及解决方法:
依赖机制几个概念:<u>https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#</u>
- 依赖传递
当 A 依赖 B、B 依赖 C ,在 A 中导入 B 后会自动导入 C ,C 是 A 的传递依赖。
依赖范围,见上文档
依赖范围由强到弱的顺序是:compile>provided>runtime>test
[图片上传失败...(image-22adb8-1657791628086)]
- 依赖冲突:
两个原则,先最近定义原则:如果树的深度相同,则按照顺序优先原则
[图片上传失败...(image-44f80e-1657791628086)]
1 解决办法:
显示添加D2.0依赖,使其更近
[图片上传失败...(image-5eaa71-1657791628086)]
样例:
项目->a->c(1.0),
项目->b->d>->c(2.0)
此时为了使用到c(2.0),可以直接在项目的pom.xml中直接引入c2.0,即此时依赖如下:
项目->c(2.0) ##直接覆盖,根据路径最短原则此时会选择c.20版本
项目->a->c(1.0)
项目->b->d>->c(2.0)
<depencies>
<dependency>
<groupId>xxx</groupId>
<artifactId>a</artifactId>
<version>xx</version>
</dependency>
<dependency>
<groupId>xxx</groupId>
<artifactId>d</artifactId>
<version>xx</version>
</dependency>
<!--通过在根pom.xml 中覆盖的方式实现-->
<dependency>
<groupId>xxx</groupId>
<artifactId>c</artifactId>
<version>2.0</version>
</dependency>
<depencies>
2、排除依赖 (最常用)
还是上面的实例,项目依赖如下:
项目->a->c(1.0),
项目->b->d>->c(2.0)
此时可以通过exclude方式在a中排除掉c1.0,如下
<depencies>
<dependency>
<groupId>xxx</groupId>
<artifactId>a</artifactId>
<version>xx</version>
<!--通过exclude方式实现-->
<exclusions>
<exclusion>
<groupId>xxxx</groupId>
<artifactId>c</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xxx</groupId>
<artifactId>d</artifactId>
<version>xx</version>
</dependency>
<depencies>
3、将版本的冲突的jar升级为相同的版本
还是上面的实例,项目依赖如下:
项目->a->c(1.0),
项目->b->d>->c(2.0),
此时可以通过在a中奖c版本升级到2.0来解决。
-
dependencyManagementde与pendencies区别
转载:<u>https://www.jianshu.com/p/c8666474cf9a</u>
1)dependencyManagement应用场景
为了项目的正确运行,必须让所有的子模块使用依赖项的统一版本,必须确保应用的各个项目的依赖项和版本一致,才能保证测试的和发布的是相同的结果。在我们项目顶层的pom文件中,我们会看到dependencyManagement元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。<u>Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的</u><u>版本号</u><u>。</u>
父pom中dependencyManagement如下:
<modules>
<module>module1</module>
</modules>
<properties>
<spring-version>3.1.1.RELEASE</spring-version>
</properties>
<dependencyManagement>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-version}</version>
</dependency>
</dependencyManagement>
子模块module1中dependency声明如下所示:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
</dependencies>
这样做的好处:统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,才能保证测试的和发布的是相同的成果,因此,在顶层pom中定义共同的依赖关系。同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。
2)dependencies应用场景
相对于dependencyManagement,如果在父pom文件中中通过dependencies引入jar,将默认被所有的子模块继承。
子模块如果希望有自己个性化的内容,可以在子模块中对于其中的某个属性进重新定义。
例如:
父pom中:
<dependencyManagement>
<dependencies>
....
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1</version>
</dependency>
....
</dependencies>
</dependencyManagement>
子模块1的pod中:
<dependencies>
....
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclusion>
</exclusions>
</dependency>
....
</dependencies>
那么,子模块1由于重新定义了spring-web的描述,因此子模块将采用自己的依赖定义,而不再使用pom中默认定义的。
3)dependencyManagement与dependencies区别
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
dependencies即使在子模块中不写该依赖项,那么子模块仍然会从父项目中继承该依赖项(全部继承)。
在实际的项目开发中,推荐在父pom中使用dependencyManagement对项目中使用到的依赖包进行统一的管理。
7.maven clean install -DskipTests构建过程
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------< com.tiger:reader >--------------------------
[INFO] Building reader 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ reader ---
[INFO] Deleting /Users/pandas/idea/reader/target
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ reader ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ reader ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/pandas/idea/reader/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ reader ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory /Users/pandas/idea/reader/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ reader ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/pandas/idea/reader/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ reader ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ reader ---
[INFO] Building jar: /Users/pandas/idea/reader/target/reader-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.6.2:repackage (repackage) @ reader ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ reader ---
[INFO] Installing /Users/pandas/idea/reader/target/reader-0.0.1-SNAPSHOT.jar to /Users/pandas/.m2/repository/com/tiger/reader/0.0.1-SNAPSHOT/reader-0.0.1-SNAPSHOT.jar
[INFOers/pandas/.m2/repository/com/tiger/reader/0.0.1-SNAPSHOT/reader-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.042 s
[INFO] Finished at: 2022-01-08T15:53:15+08:00
执行顺序:
1、使用清理插件:maven-clean-plugin:执行清理删除已有target目录;
2、使用资源插件:maven-resources-plugin:执行资源文件的处理;
3、使用编译插件:maven-compiler-plugin:编译所有源文件生成class文件至target\classes目录下(;
4、使用资源插件:maven-resources-plugin:执行测试资源文件的处理;
5、使用编译插件:maven-compiler-plugin:编译测试目录下的所有源代码;
6、使用插件:maven-surefire-plugin:运行测试用例;
7、使用插件:maven-jar-plugin:对编译后生成的文件进行打包,包名称默认为:artifactId-version,比如本例生成的jar文件:reader-0.0.1-SNAPSHOT.jar,包文件保存在target目录下;
8、使用maven-install-plugin:把上述打包生成的jar包和pom文件安装到本地的仓库中(一般默认的路径为:~/Users/.m2/repository/
8.Idea,中maven使用,以及插件 maven helper
官方文档
https://plugins.jetbrains.com/plugin/7179-maven-helper
在plugin中,搜mvn helper->选中pom文件
[图片上传失败...(image-7b1f43-1657791628085)]
9.maven的文件位置
一般在,home内,~/.m2中
mavan 经过打包会将对应的项目打包成jar报或者war形式
查看,找到项目对应的jar或war,jar是文件,war是文件夹
如果是jar包 ,vim 项目.jar ->显示对应的依赖关系
如果是springboot项目,一般在manifest.yaml 中能找到对应的路径
如果是war , cd 进去 -> 如下:
apps/项目名/current/项目名.war/WEB-INF/lib中