目录



Maven专栏目录(点击进入…)



Maven依赖管理

  • 目录
  • Maven依赖管理
  • 1.添加依赖
  • 2.重建索引
  • 依赖范围(Scope)
  • Maven依赖搜索顺序
  • 依赖传递
  • 解决依赖版本冲突
  • Maven默认
  • 1.第一声明原则
  • 2.路径近者优先原则
  • 排除原则
  • 版本锁定原则
  • 热部署
  • 项目打包带上Jar
  • 方式一:
  • 方式二:(推荐)



Maven依赖管理

1.添加依赖

点击:dependencies

maven设置依赖版本 maven依赖版本管理_开发语言

点击add

maven设置依赖版本 maven依赖版本管理_spring_02


搜索你需要的jar

maven设置依赖版本 maven依赖版本管理_maven_03


ps:如果没有显示任何东西,我们需要手动的新建一下索引


2.重建索引

打开maven仓库的视图

maven设置依赖版本 maven依赖版本管理_java_04

点击自己的本地仓库

maven设置依赖版本 maven依赖版本管理_开发语言_05

maven设置依赖版本 maven依赖版本管理_开发语言_06

右击 --> Rebuild index

然后再次手动输入要添加的坐标,选择版本

maven设置依赖版本 maven依赖版本管理_开发语言_07

可以看到 pom.xml文件中多出了如下代码

maven设置依赖版本 maven依赖版本管理_java_08



依赖范围(Scope)

Compile:编译(compile)时需要,测试时需要,运行时需要,打包时需要
Provided:编译(compile)时需要,测试(test)时也需要,运行时不需要,打包时不需要
Runtime:编译时不需要,测试时需要,运行时需要,打包时需要
Test:编译时不需要,测试时需要,运行时不需要,打包也不需要

依赖范围

编译

测试

运行

打包

Compile





Provided



Runtime




Test



Maven依赖搜索顺序

当执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:
(1)在本地仓库中搜索,如果找不到,执行步骤2,如果找到了则执行其他操作
(2)在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤4,如果找到了则下载到本地仓库中已被将来引用
(3)如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)
(4)在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库已被将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)



依赖传递

只添加了一个struts2-core依赖,发现项目中出现了很多jar,这种情况叫依赖传递

maven设置依赖版本 maven依赖版本管理_java_09

解释什么是传递依赖
举例子A依赖B,B依赖C
B是A的直接依赖
C是A的传递依赖

通过解释依赖传递,抛出问题,依赖传递会存在一个问题,啥问题呢?就是依赖版本冲突的问题

打比方:
A(项目)依赖B,B依赖C(版本是1.1版本),这个时候我又导入了依赖D,D依赖于C(1.2版本)
如果两个都进来,是不是会出现问题;版本重复,和版本冲突啊



解决依赖版本冲突

Maven默认

在平时导入jar包时即使产生了依赖冲突程序也会照样运行,这是因为maven会遵循两个原则,来解决jar包冲突

1.第一声明原则

即在pom文件中jar包坐标的导入顺序决定了发生依赖冲突时使用哪个发生冲突的jar包,先声明者优先

<dependencies>
	<dependency>
		<groupId>org.apache.struts</groupId>
		<artifactId>struts2-spring-plugin</artifactId>
		<version>2.3.37</version>
	</dependency>
<dependency>
		<groupId>org.apache.struts</groupId>
		<artifactId>struts2-spring-plugin</artifactId>
		<version>3.0.5</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.14.RELEASE</version>
	</dependency>
</dependencies>

谁先定义的,就先用谁的,这里是先用的是struts 2插件里面配置的2.3.37的版本;所以就用2.3.37版本

2.路径近者优先原则

自己添加的jar包,直接依赖高于传递依赖
即直接依赖优先于间接依赖,依赖的层级越低越优先

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-beans</artifactId>
	<version>5.0.14.RELEASE</version>
</dependency>



排除原则

排除原则是在某个不用的坐标下添加exclusion标签(也可在dependencies查看中将spring-beans jar包右键选择exclution Maven artifct)

项目A依赖于项目B,但是由于一些原因,不想引入传递性依赖C,而是自己显式声明对项目C 1.1.0版本的依赖。代码中使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。需要注意的是,声明exclusion的时候只需要groupId和artifactId,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,maven解析后的依赖中,不可能出现groupId和artifactId项目,但是version不同的两个依赖

<dependencies>
	<dependency>
		<groupId>org.apache.struts</groupId>
		<artifactId>struts2-spring-plugin</artifactId>
		<version>1.0.0</version>
		<exclusions>
			<!-- 将struts2-spring-plugin中spring-beans的传递依赖排除 -->
			<exclusion>
				<groupId>org.springframework</groupId>
				<artifactId>spring-beans</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
 
    <dependency>
      <groupId>org.apache.struts</groupId>
	  <artifactId>struts2-spring-plugin</artifactId>
	  <version>1.1.10</version>
    </dependency>
 </dependencies>

实现:通过指定的标签实现排除指定的依赖(排除了spring-beans的依赖)

版本锁定原则

可以通过指定标签锁定指定jar包的版本,保证程序在运行时采用锁定jar包的版本
例:当别人在使用程序所打成的jar包时,通过版本锁定即使使用者在程序中导入了其他版本的相同jar包,也会保证程序中的jar包版本不会发生改变,保证了程序的正常运行
注意
(1)锁定标签并不会导入依赖,如果需要导入以来还需要通过<dependency>标签来完成,通过<dependency>导入依赖时可以不声明jar包的版本,会自动导入锁定的版本jar包
(2)锁定版本的标签一般只写在父模块中,子模块可以通过继承也会受影响
(3)如果子模块中没有声明版本,并且父模块中也没有书写锁定版本的标签,则程序会报错

<!-- 配置常量的属性,防止将来框架版本升级,不需要多出修改 -->
<properties>
	<spring.version>5.0.14.RELEASE</spring.version>
	<hibernate.version>5.0.12.Final</hibernate.version>
	<struts.version>2.3.37</struts.version>
</properties>

<!--版本锁定,指定项目中依赖的版本 -->
<dependencyManagement>
	<dependencies>
		<!-- 指定spring-context的版本为5.0.14 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- 指定spring-beans的版本为5.0.14 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>
</dependencyManagement>



热部署

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
</dependency>



项目打包带上Jar

方式一:

pom文件添加以下及节点

<build>
   <resources>
      <resource>
        <directory>src/main/java</directory>
      </resource>     
    </resources>
</build>

默认的资源文件夹是src/main/resource,此方法修改了资源文件夹,让你默认的资源文件夹变成了src/main/java文件夹。而这个文件夹在maven中是默认放置源代码的
缺点:修改之后,src/main/resource文件夹就不是资源文件夹了,放在里面的文件将不会被当作资源

方式二:(推荐)

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-resources-plugin</artifactId>
	<version>2.3</version>
	<executions>
		<execution>
			<id>copy-resources</id>
			<phase>process-resources</phase>
			<goals>
				<goal>copy-resources</goal>
			</goals>
			<configuration>
			<outputDirectory>${project.build.outputDirectory}</outputDirectory>
			<resources>
				<resource>
					<directory>src/main/java</directory>
						<includes>
							<include>**/*.java</include>
						</includes>
				</resource>
			</resources>
			</configuration>
		</execution>
	</executions>
</plugin>

插件maven-resources-plugin默认处理资源和测试资源,把资源加入到文件夹${project.build.outputDirectory},这个引用表示项目的输出文件夹

一般是项目的WEB-INF\classes文件夹。等到打包的时候,就把这个文件夹里面的内容打包成jar文件。所以想要把源代码打包到jar文件里面
,就需要把源代码当作资源文件添加到文件${project.build.outputDirectory}

缺点:代码比较长
优点:不会修改资源文件夹,项目结构不用改变,推荐使用这一种