Maven依赖管理工具详细介绍
目录
1.Maven的概念
2.Maven的第一个项目
3.Maven仓库配置
4.maven在idea中的应用
4.1 maven视图
4.2 maven坐标概念
4.3依赖范围
4.4依赖传递和可选依赖
4.5maven生命周期
4.6 maven继承和聚合
4.7 Properties属性
1.Maven的概念
1.1 maven介绍
maven 是跨平台的项目管理工具。主要服务于基于Java 平台 项目的构建, 依赖管理和 项目信息管理。
项目的构建:高度自动化,跨平台,可重用的组件。标准化的
依赖:自动依赖,统一依赖管理
项目信息:项目名称描述,开发人员信息、开发者信息等
1.2 依赖管理
1.3 项目构建
项目构建:一个从编写源代码从编译、测试、运行、打包、部署的过程。
传统项目:
打开Idea编写源代码和配置文件,对源代码进行编译,可以使用Junit进行单元测试,把项目打成war包,部署到Tomcat服务器中运行
Maven:
maven将项目构建过程进行标准化,每个阶段都可以使用一个命令来完成。
清理 --> 编译 --> 测试 --> 报告 --> 打包 --> 部署
、
maven的应用场景,开发人员只要按着maven标准的目录结构进行开发即可,然后提交代码。
在测试服务器上拉取Java源码,然后可以使用maven的自动化项目构建完成项目的清理、编译、测试、打包和安装部署等
1.4
安装Maven压缩包,然后解压缩,进入目录,有如下结构:
bin:含有mvn运行的脚本
boot:含有plexus-classworlds类加载器框架
conf:含有settings.xml配置文件
lib:含有Maven运行时所需要的java类库
LICENSE.txt, NOTICE.txt, README.txt针对Maven版本,第三方软件等简要介绍
添加到环境变量,设置MAVEN_HOME环境变量,把MAVEN解压后的变量作为变量值:
然后在Path中添加bin目录
2.Maven的第一个项目
1.创建Hello目录,然后里面创建src目录,pom.xml
2.在src目录创建main目录和test目录
3.在main和test目录下,创建resources目录,
再同时创建java/com/mszlu/rpc/demo/Hello.java,编写好相关的文件
在Hello文件夹下,打开终端,执行如下命令
1.执行 mvn compile命令:(编译项目的主源代码(通常是 src/main/java
目录下的 Java 文件),生成的字节码文件会放在 target/classes
目录中)
可以发现打包生成了一个target目录
2.执行mvn clean命令:(删除项目之前构建生成的所有文件(如 target
目录),确保项目处于干净的初始状态)
将target目录清理掉了
3.执行mvn clean compile
4.执行mvn clean test (使用测试框架(如 JUnit)运行项目的测试代码,生成测试报告+控制台输出)前,target目录:
执行命令后,target目录:
5.执行mvn package:将编译后的代码打包为可分发的格式(jar包,war包,取决于项目的pom文件),并存放在target目录中
6.执行 mvn install:将打包后的文件(如 JAR/WAR)安装到本地 Maven 仓库,安装位置取决于maven 的conf中的settings.xml文件
install本身做的事情:clean → compile → test → package→ install,一共做了这5件事情
其中执行后面的命令会自动触发前面的命令。
2.依赖jar包,创建HelloFriend项目
在main/java/com/mszlu/rpc/demo/HelloFriend.java
//引入自己本地库里的jar包,(刚刚自己导入的包)
import com.mszlu.rpc.Hello;public class HelloFriend {public String sayHelloToFriend(String name){Hello hello = new Hello();String str = hello.sayHello(name)+" I am "+this.getMyName();System.out.println(str);return str;}public String getMyName(){return "HMY";}
}
在test/java/com/mszlu/rpc/demo/HelloFriend.java
import org.junit.Test;
import com.mszlu.rpc.Hello;public class HelloFriendTest {@Testpublic void testHelloFriend(){HelloFriend helloFriend = new HelloFriend();String results = helloFriend.sayHelloToFriend("LYL");assertEquals("Hello LYL! I am HMY",results); }
}
然后我们在HelloFriend目录下,打开终端,执行mvn package
执行就成功执行了,把其他包导入了.
3.Maven仓库配置
1、 何为Maven仓库?
Maven 仓库是 Maven 项目管理中用于存储和管理项目依赖(如 JAR 包、WAR 包等)的集中式存储库。
2.Maven仓库布局
1、 根据Maven坐标定义每个构建在仓库中唯一存储路径
2、路径构成: groupId/artifactId/version/artifactId-version.packaging
3、 Jar war pom(父工程做依赖管理的)
3.仓库的分类
1.本地仓库:~/.m2/repository/ 可修改;且每个用户只有一个本地仓库
2.远程仓库:1.中央仓库:Maven默认的远程仓库
2.私服:一种特殊的远程仓库,假设在局域网内的仓库
4.Maven本地仓库配置
1.全局本地仓库(所有操作系统用户均影响)
%MAVEN_HOME%\conf\settings.xml文件,修改该文件会影响所有使用该Maven的用户的本地仓库
2.用户本地仓库(仅影响使用该配置文件的用户或程序),该文件可以在任意目录,通过单独配置生效(例如在idea中设置settings.xml)
3.修改配置文件设置Maven本地仓库(以全局设置为例),将本地仓库位置设置到指定位置
4.maven在idea中的应用
4.1 maven视图
Maven项目视图主要用于查看该maven项目的各项属性,同时也可以进行一些常见的maven的操作,比如打包,清理,测试等等;
4.2 maven坐标概念
在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括groupId、artifactId、version、packaging、classifier。上述5个元素中,groupId、artifactId、version 是必须定义的,packaging 是可选的 ( 默认为 jar )。
坐标的含义:
1、groupId:组织标识,一般为:公司网址的反写+项目名(对名字没有硬性要求,能标识唯一即可),例如:
-
- Spring 框架:
org.springframework
- MyBatis框架:
org.mybatis
- 你公司的项目:
com.yourcompany.yourproject
- Spring 框架:
2、artifactId:项目名称,一般为:项目名-模块名(spring - core)
-
- Spring 框架的核心模块:
spring-core
- MyBatis 的核心库:
mybatis
(直接用项目/框架 名称作为模块名,因为它的核心功能都在这个模块中,没有更细的拆分(如mybatis-core
)。) - 你的项目模块:
user-service
、common-utils
- Spring 框架的核心模块:
3、version:版本号形式为0.0.1-SNAPSHOT:
第一个 0 表示大版本号,第二个 0 表示分支版本号,第三个 0 表示小版本号
SNAPSHOT -- 快照版本,ALPHA -- 内测版本,BETA -- 公测版本,RELEASE -- 稳定版本,GA -- 正式发布
4、packaging:打包的方式,如:pom, jar, war, ...
5、clissifier:用来帮助定义构件输出的一些附属构件。
4.3 依赖范围
Maven项目在开发工程中有三套classpath
主代码:main下面的都是主代码在编译的时候的依赖
测试代码:test下是测试代码编译的时候的依赖
运行时:main代码在运行的时候对包的依赖
依赖范围的使用,通过在引用第三方依赖时的<scope></scope>标签进行设置,例如:
其中,共有6种scope,分别是compile,provided,runtime,test,system,
import
compile(默认):编译依赖范围,默认使用该依赖范围。其下的maven依赖,对于编译、测试、运行classpath都有效。
test:测试依赖范围,只对测试classpath有效,编译主代码或运行项目时无法使用此依赖。典型例子如junit
provided:已提供依赖范围,其对于编译和测试classpath有效,运行时无效。如在web开发时,只有编译和测试才用到servlet-api,其运行时的servlet-api由web容器(如tomcat)提供,无需依赖。并且在打war包时,此范围的依赖不会打在WEB-INF/lib下
runtime:运行时依赖范围。与provided相对,运行时classpath有效。典型例子如JDBC
4.4 依赖传递和可选依赖
4.4.1依赖传递
应用场景:
第一直接依赖: HelloFriend项目依赖Hello项目
第二直接依赖: MakeFriend项目依赖HelloFriend项目
我们在 MakeFriend项目中,导入HelloFriend的jar包:
然后刷新依赖,可以发现HelloFriend依赖的Hello.jar包也自动导入了进来
这就是典型的传递依赖
4.4.2 依赖范围对传递依赖的影响
传递依赖是会受到依赖范围的影响的,具体来看结果如下:
4.4.3 依赖阻断
刚才引入HelloFriend 依赖时,自动把Hello依赖也引入了,为了不引入该依赖依赖的 其他依赖,可以使用<optional>true</optional>进行设置
在HelloFriend项目里的 pom.xml文件中加上
<dependencies><dependency><groupId>com.mszlu.rpc</groupId><artifactId>HelloFriend</artifactId><version>0.0.1-SNAPSHOT</version>
<!-- 依赖阻断,表示当HelloFriend被其他项目依赖时(比如当前MakeFriend),-->
<!-- 就不传递HelloFriend的依赖(如Hello依赖) 至 依赖于HelloFriend的项目(MakeFriend)--><optional>true</optional></dependency>
然后在MakeFriend依赖项里,引入该依赖(如果想清空所有依赖,那么可以把所有依赖项注释下,然后刷新依赖项),此时再看,便没有传递的Hello这个依赖项了
4.4.4 可选依赖阻断
当我们引入的依赖 依赖其他的依赖时,如果我们明确想排除掉某一个依赖,可以使用 <exclusions><exclusion>依赖项</exclusion></exclusions>来排除掉引用的依赖
这样引入HelloFriend依赖时,就不会引入Hello依赖了
4.5 maven生命周期
Maven的生命周期是对所有的构建过程进行抽象和统一。Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶段的执行顺序。而在执行这些阶段时,实际的工作还是由插件来完成的。这种思想与设计模式中的模板方法非常相似。
4.6 maven继承和聚合
maven继承:
统一管理子模块的公共配置,避免重复。通过定义父 POM,子模块可继承以下内容:
- 依赖管理(
dependencyManagement
) - 插件配置(
pluginManagement
) - 项目元数据(
groupId
、version
、properties
等)
1.先创建一个父项目,然后把自带的src目录删掉
2.再在父项目的基础上创建三个模块,分别是core,manage,portal
3.观察父项目的pom.xml:
其中子类项目的pom.xml:
以上这些都是IDEA自动生成的。
父项目依赖:此时如果在父项目中引入依赖,那么继承父类的这几个项目都会引入对应的依赖,如下:
1.在父项目的pom.xml中加入以下依赖
2.增量重新加载所有Maven项目
这样所有项目的依赖项都继承了父项目的依赖项
父类通过dependencyManagement管理依赖,子类默认不会继承该依赖, 但是当子类使用该依赖时无需考虑版本信息,直接继承父类dependencyManagement中设置的版本号(Version),以log4j为例:
<!-- 父项目提供一个依赖管理,主要用于管理子项目以来的版本号-->
<!-- 父项目本身也不会引入该管理中的依赖--><dependencyManagement><dependencies><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency></dependencies></dependencyManagement>
我在manage模块中的pom.xml中引入log4j依赖,此时便不用再加版本号了
此时引入的版本号便和父项目的一致
maven聚合管理:
我们在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块、system系统模块、log日志模块、reports统计模块、monitor监控模块等等。这时我们肯定会出现这么一个需要,我们需要一次构建多个模块,而不用每个模块都去mvn;
以上面得父子项目为例,当我们对parent进行mvn install时,会对core,manage和portal项目均进行install操作
此时可以看到所有下的模块都已经构建成功了
4.7 Properties属性
通过 properties元素 用户可以定义一个或多个maven属性,然后在 maven 的其他地方使用 ${属性名称} 的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以。