Maven
- 在构建java项目的时候,总是会碰到下载依赖和对项目结构的疑问,以下内容就是我对现在最常用之一的java包管理器maven的学习笔记
一、情景和作用以及前置步骤
1.1情景和作用
解决依赖管理和项目构建
-
核心文件:pom.xml,类似于package.json,makefile文件
-
类似于npm、make的作用
-
当下载依赖的时候默认是先从本地仓库查找,如果没有去就去私服仓库(可以用Nexus配置)或者中央仓库寻找。
-
项目的构建需要将源文件编译成一个jar包或war包,maven提供了自动化的标准流程,通过该流程可以实现自动化打包
1.2前置步骤
1.2.1安装maven
-
前备知识
- 需要JDK版本>=1.7
-
下载链接
-
配置setting.json
-
配置maven依赖安装路径
xml<localRepository><路径></localRepository>
-
配置镜像源
xml<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> <mirror> <id>maven-default-http-blocker</id> <!-- 镜像的唯一表示 --> <mirrorOf>external:http:*</mirrorOf> <!-- 镜像的范围,*表示匹配所有,该镜像只对http协议有效,https协议无效,--> <name>Pseudo repository to mirror external repositories initially using HTTP.</name> <url>http://0.0.0.0/</url> <blocked>true</blocked> </mirror>
-
(可以不配)指定maven默认打包java项目的JDK版本。但是因为项目中的pom.xml优先级高于它,java项目一般也会在pom.xml中指定JDK版本
xml<profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile>
-
1.2.2简单开始maven
-
创建maven项目
shellmvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
- -DgroupId代表的是域名(通常反过来写)
- -DartifactId是项目的唯一标识
- -DarchetypeArtifactId项目的目录结构
shell目录结构 my-app |-- pom.xml `-- src |-- main | `-- java | `-- com | `-- mycompany | `-- app | `-- App.java `-- test `-- java `-- com `-- mycompany `-- app `-- AppTest.java
-
流程
-
编译项目
shellmvn compile
-
测试项目(测试代码的逻辑性)
shellmvn test
-
打包项目(打包使得源代码和环境集合在一起,实现可移植性,适合企业开发)
shellmvn package
-
执行项目
-
如果你的项目是一个 可执行的 JAR 文件 ,你可以使用
java -jar
命令来运行它。首先,确保你的pom.xml
文件中有一个mainClass
配置用于指定主类。典型的配置如下:xml<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <archive> <manifest> <mainClass>com.mycompany.app.App</mainClass> <!-- 主类路径 --> </manifest> </archive> </configuration> </plugin> </plugins> </build>
shelljava -jar target/my-app-1.0-SNAPSHOT.jar
-
直接运行项目中的主类
-
如果你想直接运行某个类(不打包),可以使用 Maven 的
exec:java
插件。首先,确保在pom.xml
文件中添加了exec-maven-plugin
插件:xml<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <configuration> <mainClass>com.mycompany.app.App</mainClass> <!-- 主类路径 --> </configuration> </plugin> </plugins> </build>
shellmvn exec:java -Dexec.mainClass="com.mycompany.app.App"
-
-
-
清理项目
shellmvn clean
-
1.2.3idea中使用maven
-
创建项目,大部分框架都集成了maven,都有默认的maven项目目录结构,默认配置。可以通过下图的地方去修改maven配置
这里maven home path就是自己的maven下载路径,改User setting file<setting.xml的路径>和Local repository记得勾选旁边的Override。
二、基础知识
2.1Maven的生命周期和插件
-
右边maven中的Profiles(比如不同java版本)是setting.json中配置的,如果配置多个就会有多个,但是一般的Spring项目没有的,因为在生成项目的时候,我们会指定很多参数,并不是单纯的maven项目,是在pom.xml中配置的,当然也可以实现在pom.xml中配置实现不同版本的切换
-
Lifecycle这些生命周期是依靠于下方的一个或多个插件的,idea中可以直接点击生命周期执行
阶段 描述 对应命令 clean
清理项目,删除上一次构建生成的文件 mvn clean
validate
验证项目是否正确且所有必要信息都可用 mvn validate
compile
编译源代码 mvn compile
test
使用适当的测试框架执行测试 mvn test
package
将编译后的代码打包成可分发格式,如 JAR 或 WAR mvn package
verify
运行任何检查,验证包的有效性 mvn verify
install
将包安装到本地 Maven 仓库 mvn install
site
生成项目的站点文档 mvn site
- 一般的顺序也是这样
- groupId、artifactId、version构成了jar包的唯一标识
- 命令行支持
mvn <阶段> <阶段>
这种操作,是先执行第一个任务,再第二个任务
2.2maven的核心特性:依赖下载管理
-
scope标签
-
属性
下面是用 Markdown 格式编写的 Maven
scope
属性作用总结表:Scope 编译时 测试时 运行时 最终打包 用途 compile
是 是 是 是 默认值,依赖在编译、测试、运行时都可用,通常用于核心库。 runtime
否 是 是 是 依赖在运行时可用,编译时不可用,适用于编译时不需要但运行时需要的库(如 JDBC 驱动)。 test
否 是 否 否 仅在测试阶段可用,不会包含在最终构建中,适用于测试框架(如 JUnit、Mockito)。 system
是 是 是 否 使用本地文件路径的依赖,不从 Maven 仓库下载,需通过 systemPath
指定。provided
是 是 否 否 编译、测试时可用,运行时由目标环境提供,不打包在最终项目中(如 Servlet API)。 -
极其不推荐
system
,因为转移开发环境很容易出问题 -
pom.xml中下载依赖的时候,本身就会通过配置过的maven的repository仓库来寻找依赖,找到了就不用下载。也可以通过把scpoed属性值改为system,再加上system-path路径使得使用别的路径的依赖,但上方也说了极其不推荐
-
-
添加依赖
-
进入maven的repository仓库网站
https://mvnrepository.com/
-
搜索需要下载的依赖
-
选择版本号
-
点击版本号,复制链接,并加入pom.xml
-
-
依赖传递
- 直接写在pom.xml的依赖是直接依赖,写到xml中的文件有可能依赖别的文件,依赖的文件就和现在的项目的关系就是间接依赖了,maven会帮我们自动解析,但是要注意,maven只会解析属性scpoed值为compile的依赖(但如果是在父模块中定义的就不是了)
-
依赖冲突:使用同一个依赖的不同版本
-
最短路径选择:当你拉取其他人的仓库时,如果该仓库依赖于不同版本的同一库,Maven 会根据依赖树的最短路径原则选择版本。这意味着如果某个依赖通过更少的中间依赖达到目的,它会被优先选择。
-
优先级 :在自己的项目中,列出的依赖顺序也会影响最终选择的版本。通常,首先出现的依赖会被优先使用,这使得在
pom.xml
中的依赖顺序变得重要。 -
手动解决依赖
-
当一个模块使用了其它两个模块的jar包,每个jar包都有spring-jdbc,但版本不一样,这个时候,maven有自动的调节方案,可以看到child-test3这个模块的jdbc黑了
-
如果我就要使用test3的怎么办呢
-
使用exclusions标签,再在里面加入单数的exclusion标签,添加要忽略的jar包的坐标,注意不需要版本号,因为会把该jar包所有的这个类型的依赖全部忽略掉,然后重启,发现test2没了,test3也黑,是因为ideabug,重启后就ok了
-
在所需的jar包的pom.xml文件中加入optional选项,true就是屏蔽,有图和第一个方法有同样bug,重启idea即可
-
-
-
-
-
父子项目
-
当多个子模块需要的依赖都一样,可以通过父模块安装好,供子模块使用,父模块不会打包。比如电商平台会有:商品模块、用户模块等
-
新建一个项目,父模块不需要打包等操作,可以直接删除src文件夹。
- 注意把父模块中的pom.xml中的packaging改为pom,表示不需要打包,一般来说都是jar包,web项目为war包。
- 然后会出现modules标签,里面是子模块的信息。
-
新建一个子模块
子模块的pom.xml,parent直接移用了父模块的坐标,子模块的groupId直接继承父模块的groupId
-
注意spring,项目不会直接继承夫模块的groupId,而是单独拥有,会有以下好处
1. 模块化和独立性
- 使用不同的
groupId
可以使每个子模块更加独立,便于管理和维护。这样,子模块可以在不同的项目中独立使用,避免了依赖于父模块的紧耦合关系。
2. 版本控制
- 不同的
groupId
可以让子模块拥有独立的版本控制。这意味着可以单独更新子模块的版本,而不影响父模块或其他子模块。
3. 发布和分发
- 当子模块需要单独发布到 Maven 仓库时,使用不同的
groupId
可以确保它们可以被其他项目直接引用。这在企业级开发中尤其常见。
4. 清晰的组织结构
- 采用不同的
groupId
可以帮助在项目中建立更清晰的层次结构和模块组织,便于团队成员理解各个模块的用途和职责。
5. 避免冲突
- 如果子模块和父模块的
groupId
相同,可能会在依赖解析时引发混淆或冲突。使用不同的groupId
可以避免这种情况。
6. 符合 Maven 约定
- Maven 鼓励通过
groupId
来反映项目的组织结构或领域。不同的groupId
可以更好地反映子模块的业务逻辑或功能特性。
- 使用不同的
-
-
dependencyManagement
-
在这个标签中定义的模块不会被子模块直接继承,在子模块中再引入模块,不写版本号,就是直接引用父模块中的
-
-
spring.version多个依赖使用同个版本
使用方式如图
-
参考GeekHour'
-
如有问题,可以反馈给我,感谢读者的观看啦