maven依赖详解

简介: maven依赖详解

1. maven基础

1.1 简介

maven 是一个项目管理工具,主要作用是在项目开发阶段对Java项目进行依赖管理和项目构建。

依赖管理:就是对jar包的管理。通过导入maven坐标,就相当于将仓库中的jar包导入了当前项目中。

项目构建:通过maven的一个命令就可以完成项目从清理、编译、测试、报告、打包,部署整个过程。

1.2 仓库类型

  1. 本地仓库
  2. 远程仓库

①maven中央仓库

②maven私服(公司局域网内的仓库,如Nexus)

③其他公共远程仓库

1.3 常用命令

命令 描述
mvn clean 对项目进行清理,删除target目录下编译的内容
mvn validate 验证工程是否正确,所有需要的资源是否可用
mvn compile 编译当前的工程,将Java文件编译成.class文件(真正在jvm里面运行的文件)
mvn test 对项目进行运行测试
mvn package 打包文件并存放到项目的target目录下,打包好的文件通常都是编译后的class文件
mvn verify 运行任何检查,验证包是否有效且达到质量标准
mvn install 在本地仓库生成仓库的安装包,可供其他项目引用,同时打包后的文件放到项目的target目录下
mvn site 生成项目相关信息的网站
mvn deploy 发布工程至指定的远端仓库当中,可以被其他机器通过pom坐标引用

1.4 场景举例

mvn clean package

依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段

package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库


mvn clean install

依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段

install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库


mvn clean deploy

依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段

deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

1.5 指令总结

---------------实际应用-----------------------
# 1、刷新子模块版本号: 
mvn versions:update-child-modules
# 2、重新打包到maven本地库: 
mvn clean install -Dmaven.test.skip=true
mvn install
# 3、部署包到远程服务器
mvn clean deploy -Dmaven.test.skip=true

#---------------------一般常用命令-----------------------
# 该命令打印出所有的java系统属性和环境变量
mvn  help:system 自动在本用户下创建   ~/.m2/repository
# 清理输出目录默认target/
mvn clean
mvn clean compile     清理编译
# maven test,但实际执行的命令有:clean:clean,resource:resources,compiler:compile, resources:testResources, compiler:testCompile,maven在执行test之前,会先自动执行项目主资源处理,主代码编译,测试资源处理,测试代码编译等工作,测试代码编译通过之后默认在target/test-calsses目录下生成二进制文件,紧接着surefile:test 任务运行测试,并输出测试报告,显示一共运行了多少次测试,失败成功等等
mvn clean test  清理测试
mvn clean package 清理打包
mvn clean install  清理将打包好的jar存入 本地仓库  注意是本地仓库
mvn clean deploy  根据pom中的配置信息将项目发布到远程仓库中 

echo %MAVEN_HOME%:查看maven安装路径

---------------------创建项目-------------------------------
mvn -version/-v    显示版本信息
mvn archetype:generate  创建mvn项目,使用Archetype生成项目骨架
mvn archetype:create -DgroupId=com.oreilly -DartifactId=my-app 创建mvn项目
# 创建Maven的普通java项目:
mvn archetype:create -DgroupId=packageName -DartifactId=projectName 
# 创建Maven的Web项目:  
mvn archetype:create -DgroupId=packageName   -DartifactId=webappName-DarchetypeArtifactId=maven-archetype-webapp   

---------------------优化依赖命令-------------------------------
mvn dependency:list   显示所有已经解析的所有依赖
mvn dependency:tree  以目录树的形式展现依赖,  最高层为一层依赖 其次二层依赖 三层依赖....
mvn dependency:analyze  第一部分显示 已经使用但是未显示依赖的的  第二部分显示项目未使用的但是依赖的

---------------------第三方jar 发布到远程仓库---------------------
mvn deploy:deploy-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DrepositoryId=maven-repository-inner -Durl=ftp://xxxxxxx/opt/maven/repository/

---------------------第三方jar 安装到本地仓库---------------------
mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DdownloadSources=true -DdownloadJavadocs=true

#你是否因为记不清某个插件有哪些goal而痛苦过,你是否因为想不起某个goal有哪些参数而苦恼,那就试试这个命令吧,它会告诉你一切的.参数: 1. -Dplugin=pluginName   2. -Dgoal(或-Dmojo)=goalName:与-Dplugin一起使用,它会列出某个插件的goal信息,如果嫌不够详细,同样可以加-Ddetail.(注:一个插件goal也被认为是一个 “Mojo”)
mvn help:describe -Dplugin=help -Dmojo=describe

mvn -e    显示详细错误 信息.
mvn validate  验证工程是否正确,所有需要的资源是否可用。
mvn test-compile 编译项目测试代码。 。
mvn integration-test  在集成测试可以运行的环境中处理和发布包。
mvn verify    运行任何检查,验证包是否有效且达到质量标准。 
mvn generate-sources  产生应用需要的任何额外的源代码,如xdoclet。

1.6 依赖范围

依赖范围 对于编译classpath有效 对于测试classpath有效 对于运行classpath有效 例子
compile Y Y Y spring-core
test - Y - Junit
provided Y Y - servlet-api
runtime - Y Y JDBC驱动
system Y Y - 本地的,maven仓库之外的类库


1.7 maven 的 settings.xml 说明

#  1. 声明规范
<?xml version="1.0" encoding="UTF-8"?>
<settings 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/settings-1.0.0.xsd">

# 2. localRepository 本地仓库配置
 <!-- 本地仓库的路径。默认值为${user.home}/.m2/repository。 -->
<localRepository>usr/local/maven</localRepository>

# 3. interactiveMode
 <!--Maven是否需要和用户交互以获得输入。如果Maven需要和用户交互以获得输入,则设
 置成true,反之则应为false。默认为true。-->
<interactiveMode>true</interactiveMode>

# 4. usePluginRegistry
<!--Maven是否需要使用plugin-registry.xml文件来管理插件版本。如果需要让Maven
使用文件${user.home}/.m2/plugin-registry.xml来管理插件版本,则设为true。
默认为false。-->
<usePluginRegistry>false</usePluginRegistry>

# 5. offline
<!--表示Maven是否需要在离线模式下运行。如果构建系统需要在离线模式下运行,则为true,默认为false。
当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用。 -->
<offline>false</offline>

# 6. pluginGroups
<!--当插件的组织Id(groupId)没有显式提供时,供搜寻插件组织Id(groupId)的列
表。该元素包含一个pluginGroup元素列表,每个子元素包含了一个组织Id(groupId)。
当我们使用某个插件,并且没有在命令行为其提供组织Id(groupId)的时候,Maven就会
使用该列表。默认情况下该列表包含了org.apache.maven.plugins和org.codehaus.mojo -->
<pluginGroups>
  <!--plugin的组织Id(groupId) -->
  <pluginGroup>org.codehaus.mojo</pluginGroup>
</pluginGroups>

# 7. proxies
<!--用来配置不同的代理,多代理profiles 可以应对笔记本或移动设备的工作环境:通过
简单的设置profile id就可以很容易的更换整个代理配置。 -->
<proxies>
  <!--代理元素包含配置代理时需要的信息-->
  <proxy>
   <!--代理的唯一定义符,用来区分不同的代理元素。-->
   <id>myproxy</id>
   <!--该代理是否是激活的那个。true则激活代理。当我们声明了一组代理,而某个时候只需要激活一个代理的时候,该元素就可以派上用处。 -->
   <active>true</active>
   <!--代理的协议。 协议://主机名:端口,分隔成离散的元素以方便配置。-->
   <protocol>http</protocol>
   <!--代理的主机名。协议://主机名:端口,分隔成离散的元素以方便配置。  -->
   <host>proxy.somewhere.com</host>
   <!--代理的端口。协议://主机名:端口,分隔成离散的元素以方便配置。 -->
   <port>8080</port>
   <!--代理的用户名,用户名和密码表示代理服务器认证的登录名和密码。 -->
   <username>proxyuser</username>
   <!--代理的密码,用户名和密码表示代理服务器认证的登录名和密码。 -->
   <password>somepassword</password>
   <!--不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,使用逗号分隔也很常见。-->
   <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts>
  </proxy>
</proxies>

# 8. servers
<!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。-->
<servers>
  <!--服务器元素包含配置服务器时需要的信息 -->
  <server>
   <!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。-->
   <id>server001</id>
   <!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
   <username>my_login</username>
   <!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。密码加密功能已被添加到2.1.0 +。详情请访问密码加密页面-->
   <password>my_password</password>
   <!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)以及如果需要的话,一个密语。将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 -->
   <privateKey>${usr.home}/.ssh/id_dsa</privateKey>
   <!--鉴权时使用的私钥密码。-->
   <passphrase>some_passphrase</passphrase>
   <!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 -->
   <filePermissions>664</filePermissions>
   <!--目录被创建时的权限。 -->
   <directoryPermissions>775</directoryPermissions>
  </server>
</servers>

# 9. mirrors
<!--为仓库列表配置的下载镜像列表。高级设置请参阅镜像设置页面 -->
<mirrors>
  <!--给定仓库的下载镜像。 -->
  <mirror>
   <!--该镜像的唯一标识符。id用来区分不同的mirror元素。 -->
   <id>planetmirror.com</id>
   <!--镜像名称 -->
   <name>PlanetMirror Australia</name>
   <!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 -->
   <url>http://downloads.planetmirror.com/pub/maven2</url>
   <!--被镜像的服务器的id。例如,如果我们要设置了一个Maven中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成central。这必须和中央仓库的id central完全一致。-->
   <mirrorOf>central</mirrorOf>
  </mirror>
</mirrors>

# 10. profiles
<!--根据环境参数来调整构建配置的列表。settings.xml中的profile元素是pom.xml中profile元素的裁剪版本。它包含了id,activation, repositories, pluginRepositories和 properties元素。这里的profile元素只包含这五个子元素是因为这里只关心构建系统这个整体(这正是settings.xml文件的角色定位),而非单独的项目对象模型设置。如果一个settings中的profile被激活,它的值会覆盖任何其它定义在POM中或者profile.xml中的带有相同id的profile。 -->
<profiles>
  <!--根据环境参数来调整的构件的配置-->
  <profile>
   <!--该配置的唯一标识符。 -->
   <id>test</id>
   </profile>
</profiles>

# 11. Activation
<!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。如POM中的
profile一样,profile的力量来自于它能够在某些特定的环境中自动使用某些特定的值;
这些环境通过activation元素指定。activation元素并不是激活profile的唯一方式。
settings.xml文件中的activeProfile元素可以包含profile的id。profile也可以通
过在命令行,使用-P标记和逗号分隔的列表来显式的激活(如,-P test)。-->
   <activation>
    <!--profile默认是否激活的标识-->
    <activeByDefault>false</activeByDefault>
    <!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。-->
    <jdk>1.5</jdk>
    <!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。-->
    <os>
     <!--激活profile的操作系统的名字 -->
     <name>Windows XP</name>
     <!--激活profile的操作系统所属家族(如 'windows')  -->
     <family>Windows</family>
     <!--激活profile的操作系统体系结构  -->
     <arch>x86</arch>
     <!--激活profile的操作系统版本-->
     <version>5.1.2600</version>
    </os>
    <!--如果Maven检测到某一个属性(其值可以在POM中通过${name}引用),其拥有对应的name = 值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段-->
    <property>
     <!--激活profile的属性的名称-->
     <name>mavenVersion</name>
     <!--激活profile的属性的值 -->
     <value>2.0.3</value>
    </property>
    <!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。-->
    <file>
     <!--如果指定的文件存在,则激活profile。 -->
     <exists>${basedir}/file2.properties</exists>
     <!--如果指定的文件不存在,则激活profile。-->
     <missing>${basedir}/file1.properties</missing>
    </file>
   </activation>

# 12. properties : note:如果该profile被激活,则可以再POM中使用${user.install}
<!--对应profile的扩展属性列表。Maven属性和Ant中的属性一样,可以用来存放一些
值。这些值可以在POM中的任何地方使用标记${X}来使用,这里X是指属性的名称。属性有五
种不同的形式,并且都能在settings.xml文件中访问。
   1. env.X: 在一个变量前加上"env."的前缀,会返回一个shell环境变量。例如,"env.PATH"指代了$path环境变量(在Windows上是%PATH%)。
   2. project.x:指代了POM中对应的元素值。例如: <project><version>1.0</version></project>通过${project.version}获得version的值。
   3. settings.x: 指代了settings.xml中对应元素的值。例如:<settings><offline>false</offline></settings>通过 ${settings.offline}获得offline的值。
   4. Java System Properties: 所有可通过java.lang.System.getProperties()访问的属性都能在POM中使用该形式访问,例如 ${java.home}。
   5. x: 在<properties/>元素中,或者外部文件中设置,以${someVar}的形式使用。 -->
   <properties>
   <user.install>${user.home}/our-project</user.install>
   </properties>
   
# 13. activeProfiles
<!--手动激活profiles的列表,按照profile被应用的顺序定义activeProfile。 该元
素包含了一组activeProfile元素,每个activeProfile都含有一个profile id。任何
在activeProfile中定义的profile id,不论环境设置如何,其对应的
  profile都会被激活。如果没有匹配的profile,则什么都不会发生。例如,env-
 test是一个activeProfile,则在pom.xml(或者profile.xml)中对应id的profile
 会被激活。如果运行过程中找不到这样一个profile,Maven则会像往常一样运行。 -->
   <activeProfiles>
    <!-- -->
    <activeProfile>env-test</activeProfile>
   </activeProfiles>

# 14. Repositories
<!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 -->
   <repositories>
    <!--包含需要连接到远程仓库的信息 -->
    <repository>
     <!--远程仓库唯一标识-->
     <id>codehausSnapshots</id>
     <!--远程仓库名称 -->
     <name>Codehaus Snapshots</name>
     <!--如何处理远程仓库里发布版本的下载-->
     <releases>
      <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。  -->
      <enabled>false</enabled>
      <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
      <updatePolicy>always</updatePolicy>
      <!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。-->
      <checksumPolicy>warn</checksumPolicy>
     </releases>
     <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素-->
     <snapshots>
      <enabled/><updatePolicy/><checksumPolicy/>
     </snapshots>
     <!--远程仓库URL,按protocol://hostname/path形式 -->
     <url>http://snapshots.maven.codehaus.org/maven2</url>
     <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
     <layout>default</layout>
    </repository>
   </repositories>
   <!--发现插件的远程仓库列表。仓库是两种主要构件的家。第一种构件被用作其它构件的依赖。这是中央仓库中存储的大部分构件类型。另外一种构件类型是插件。Maven插件是一种特殊类型的构件。由于这个原因,插件仓库独立于其它仓库。pluginRepositories元素的结构和repositories元素的结构类似。每个pluginRepository元素指定一个Maven可以用来寻找新插件的远程地址。-->
   <pluginRepositories>
    <!--包含需要连接到远程插件仓库的信息.参见profiles/profile/repositories/repository元素的说明-->
     <pluginRepository>          
       <releases>     
        <enabled/><updatePolicy/><checksumPolicy/>
       </releases>
       <snapshots>
        <enabled/><updatePolicy/><checksumPolicy/>
       </snapshots>
       <id/><name/><url/><layout/>
     </pluginRepository>
   </pluginRepositories>

2. maven依赖

2.1 依赖传递

在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。


通过上面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。


2.2 手动声明

optional是maven依赖jar时的一个选项,表示该依赖是可选的,不会被依赖传递。

例如当前项目是A,A要依赖B,A依赖B的配置中加上 true,表示依赖可选

<dependency>
  <groupId>com.projecct</groupId>
  <artifactId>B</artifactId>
  <version>1.0</version>
  <scope>compile</scope>
  <optional>true</optional>
</dependency>

那么以后所有声明依赖A的项目如果也依赖B,就必须写手动声明。


比如C依赖A和B,如果C只声明了对A的依赖,那么B不会自动加入依赖,需要重新声明对B的依赖。


这种方式排除不了我项目中对第三方jar包所依赖的其他依赖,因为我不可能去修改第三方jar包的pom文件,所以只适合在项目组内部使用。

2.3 冲突解决

2.3.1第一声明者优先原则

在 pom 文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。

结论:通过上图可以看到,spring-aop和spring-webmvc都传递过来了spring-beans,但是因为spring-aop在前面,所以最终使用的spring-beans是由spring-aop传递过来的,而spring-webmvc传递过来的spring-beans则被忽略了。


2.3.2 排除

可以使用exclusions标签将传递过来的依赖排除出去。



上图我们可以看到,spring-webmvc传递过来的spring-core已经排除出去了

2.3.3 版本锁定

采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用


①在dependencyManagement标签中锁定依赖的版本


②在dependencies标签中声明需要导入的maven坐标

上图可以看出spring-core和spring-aop的版本号均已修改

目录
相关文章
|
1天前
|
存储 安全 Java
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
12 4
2024ide构建maven项目是总是卡在解析Maven依赖项目 加速方案
|
4天前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入外部依赖,如 LDAP 帮助库 ldapjdk.jar,通常涉及将 jar 放入 `src/lib` 并在 `pom.xml` 添加系统依赖
|
5天前
|
Java 数据库连接 数据库
在Maven或者Gradle构建配置中添加了必要的依赖
在Maven或者Gradle构建配置中添加了必要的依赖
14 1
|
13天前
|
Java API Maven
如何定位、解决maven依赖冲突问题
如何定位、解决maven依赖冲突问题
24 0
如何定位、解决maven依赖冲突问题
|
15天前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入外部依赖,如 LDAP 操作库 ldapjdk.jar,首先将 jar 文件放入 src/lib 文件夹。接着在 pom.xml 的 dependencies 部分添加依赖配置,
|
24天前
|
Java Maven Spring
Maven 依赖搜索顺序
Maven在构建时按顺序搜索依赖:先本地仓库,再中央仓库,接着未配置远程仓库会报错;已配置则尝试远程仓库,找到后下载至本地。为解决国内访问慢问题,可修改`settings.xml`,添加阿里云仓库镜像。在`mirrors`节点加入阿里云公共仓库或特定代理如`spring`仓库的URL。在`pom.xml`中指定依赖并运行`mvn install`。
|
1月前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入 LDAP 操作的 ldapjdk.jar 第三方库,需将 jar 文件放入 src/lib 文件夹,并在 pom.xml 的 dependencies 部分添加依赖项。
|
28天前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入 LDAP 帮助库 ldapjdk.jar,需在 `pom.xml` 的 dependencies 部分添加依赖。
|
21天前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入 LDAP 帮助库 ldapjdk.jar,首先在 src/lib 添加该 jar 文件,
|
1月前
|
Java Maven
Maven 引入外部依赖
在 Maven 项目中引入 LDAP 操作库 ldapjdk.jar,需将 jar 文件放入 src/lib 文件夹,并在 pom.xml 的 dependencies 部分添加依赖配置

推荐镜像

更多