前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >maven使用总结

maven使用总结

作者头像
爱撒谎的男孩
发布2019-12-31 15:37:43
4690
发布2019-12-31 15:37:43
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

文章目录

1. Maven使用总结

1.1. 依赖范围

1.2. 依赖传递

1.2.1. 注意

1.3. 依赖排除

1.4. 依赖原则

1.4.1. 依赖路径最短优先原则

1.4.2. pom文件中申明顺序优先

1.4.3. 覆写优先

1.5. 生命周期

1.5.1. 生命周期调用的特点

1.5.2. clean生命周期

1.5.3. default生命周期

1.5.4. Site生命周期

1.6. Maven统一管理依赖的版本号

1.7. 继承

1.7.1. 步骤

1.8. 聚合

1.8.1. 步骤

Maven使用总结

依赖范围

  • maven创建的工程的目录中包含maintest文件夹,分别表示主程序的文件夹和测试程序的文件夹
  • maven使用scop设置依赖范围,常用的依赖范围如下:
    1. compile :编译依赖范围,在测试和运行都有效,这个是默认的依赖范围
      • 对主程序是否有效:有效
      • 对测试程序是否 有效: 有效
      • 是否参与打包:参与``
      • 是否参与部署:参与
    2. test:测试依赖的范围
      • 对主程序是否有效:无效
      • 对测试程序是否 有效: 有效
      • 是否参与打包:不参与
      • 典型的例子: junit
    3. provided
      • 对主程序是否有效: 有效
      • 对测试程序是否有效:有效
      • 是否参与打包:不参与
      • 是否参与部署:不参与
      • 典型的例子:servlet-api
        • 主要解决在开发中需要用到的,但是在部署的时候不需要的依赖,比如servlet-api,在开发中没有Tomcat运行环境,因此需要这个servlet-api,但是一旦部署在Tomcat中,Tomcat中会提供这个servlet-api,如果此时在添加的话会产生依赖冲突
    4. Runtime :测试和运行时需要。编译不需要。如JDBC驱动包
      • 对测试程序是否有效:有效
      • 对主程序是否有效:有效
      • 是否参与部署: 参与
      • 是否参与打包:参与
    5. system:系统依赖范围。本地依赖,不在maven中央仓库
      • 这个必须和systemPath结合使用,用来指定本地依赖的位置
代码语言:javascript
复制
<!-- 添加服务提供者的jar接口 -->
		<dependency>
			<groupId>cn.tedu.dubbo</groupId>
			<artifactId>dubbo-provider</artifactId>
			<version>0.0.1</version>
			<scope>system</scope>
			<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/dubbo-provider-helloService-0.0.1.jar</systemPath>
		</dependency>

依赖传递

  • 在开发项目的时候,我们通常需要建立多个项目,如果一个项目中需要用到另外一个项目的类或者数据,那么需要引入这个项目快照
  • 如果HelloFriend项目依赖Hello这个项目,此时的HelloFriendpom.xml文件如下:
代码语言:javascript
复制
<project 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/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cn.tedu</groupId>
	<artifactId>HelloFriend</artifactId>
	<version>0.0.1-SNAPSHOT</version>
    
	<dependencies>
		<!-- 添加Hello这个项目的依赖快照 -->
		<dependency>
			<groupId>cn.tedu</groupId>
			<artifactId>Hello</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
    
</project>
  • 此时项目HelloFriend中存在依赖只有Hello项目这个jar,但是如果我们在Hello项目的pom.xml文件中添加一个junit的依赖,这个依赖范围为设置为compile,如下:
代码语言:javascript
复制
<dependencies>
  		<!-- Junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>compile</scope>
		</dependency>
  </dependencies>
  • 做了上面的操作,我们可以查看项目HelloFriendHello中都自动的导入了Junit依赖,这个就是依赖传递。

注意

  • 依赖传递只有是依赖范围为compile的情况下才有作用,如果我们需要一个servlet-api的依赖,因为servlet-api这个jar在部署的时候会和Tomcat冲突,因此只能设置为provided,但是此时就不能依赖传递了,只能在每个项目中的pom.xml文件中都添加了

依赖排除

  • HelloFriend项目依赖Hello项目,其中compile范围的依赖都会导入HelloFriend
  • 使用dubbo默认会添加给我们添加spring-framework的版本为2.5.6,默认添加的依赖只能排除,不能在项目中再添加一个其他的版本,只有排除之后才能添加,否则会导致jar包冲突
  • Hello项目中的依赖为:
代码语言:javascript
复制
<!-- Junit -->
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
		<scope>compile</scope>
	</dependency>
	<!-- 添加dubbo依赖的jar,会自动添加spring 2.5版本的依赖 -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>dubbo</artifactId>
		<version>2.5.3</version>
	</dependency>
  • 此时HelloFriend的项目需要使用4.3.13版本的spring,那么我们有如下解决办法:
    1. Hello项目中改变依赖,排除spring2.5版本的:
      • 一般在公司中项目的版本都是定制好的,我们不可能随意改动父项目中定义好的版本,因此这个方法明显是不行的
代码语言:javascript
复制
 <!-- 使用spring4.3.13 -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.3.13.RELEASE</version>
</dependency>
  
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>dubbo</artifactId>
	<version>2.5.3</version>
          <!--排除spring2.5版本-->
          <exclusions>
		<exclusion>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
		</exclusion>
	</exclusions>
</dependency>
  1. 我们可以在项目HelloFriend排除这个spring的依赖,那么我们就可以不需要改变Hello项目中的依赖了,如下:
    • 这个才是正确的排除依赖的方式
代码语言:javascript
复制
<!-- SpringMVC -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.3.13.RELEASE</version>
</dependency>

<!-- 添加Hello这个项目的依赖快照 -->
<dependency>
	<groupId>cn.tedu</groupId>
	<artifactId>Hello</artifactId>
	<version>0.0.1-SNAPSHOT</version>
          <!--排除项目中的spring2.5的依赖,这个不会影响Hello项目中的版本-->
	<exclusions>
		<exclusion>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
		</exclusion>
	</exclusions>
</dependency>

依赖原则

依赖路径最短优先原则

  • 假设项目MakeFriend依赖HelloFriend,并且HelloFriend依赖Hello项目。此时Hello项目中使用的log4j 1.2.14版本的,但是在HelloFriend版本中使用的是log4j1.2.17版本的,那么此时的MakeFriend应该选择什么版本呢?
  • Hello的依赖如下:
代码语言:javascript
复制
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.14</version>
</dependency>
  • HelloFriend依赖如下:
代码语言:javascript
复制
<!-- 添加Hello这个项目的依赖快照 -->
	<dependency>
		<groupId>cn.tedu</groupId>
		<artifactId>Hello</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</dependency>
	
	<!--添加1.2.17版本的log4j-->
	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version>1.2.17</version>
	</dependency>
  • MakeFriend的依赖如下:
代码语言:javascript
复制
<dependency>
	<groupId>cn.tedu</groupId>
	<artifactId>HelloFriend</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>
  • 我们根据图形可以看到MakeFriendHelloFriendlog4j1.2.17的路径是2,但是到Hello中的log4j1.2.14的路径为3,因此Maven会选择HelloFriend中的log4j1.2.17版本作为MakeFriend的依赖

pom文件中申明顺序优先

  • 路径都是一样的情况下,那么就要看在pom.xml文件中申明的顺序了,先申明的就使用哪个项目中的依赖版本
  • 假设现在的依赖改变了,MakeFriend现在是直接依赖HelloHelloFriend,如下图
  • 我们可以看出此时到两个版本的依赖都是一样的路径为2,那么我们应该选择哪个版本呢,此时就需要看看在MakeFriend中的pom.xml文件的申明顺序
    • 可以看出先申明的是HelloFriend,因此MakeFriend使用的是log4j1.2.17
代码语言:javascript
复制
<!-- 先申明HelloFriend,那么就要使用log4j.1.2.17版本 -->
		<dependency>	
			<groupId>cn.tedu</groupId>
			<artifactId>HelloFriend</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		
		<dependency>
			<groupId>cn.tedu</groupId>
			<artifactId>Hello</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

覆写优先

生命周期

  • maven的生命周期有三个部分组成,分别为clean生命周期site生命周期default生命周期

生命周期调用的特点

  • 三大生命周期中也会包含各个阶段,并且各个阶段是有序进行的,maven为了实现构建的自动化,如果我们使用了命令调用生命周期后面的处理阶段,那么会从最前面的阶段开始执行,不用每一个阶段都执行一遍。

clean生命周期

  • 在进行真正的构建之前进行一些清理工作
  • clean生命周期包括:
    • per-clean:执行了一些需要在clean之前完成的工作
    • clean:移除所有上一次构建生成的文件
    • post-clean:执行一些需要在clean之后立刻完成的工作
  • 当我们执行mvn:clean命令的时候只会执行per-cleanclean这两个阶段的任务,不会执行post-clean的工作

default生命周期

  • 构建的核心部分,编译、测试、打包、部署
  • 包括如下的23个生命周期阶段:

生命周期阶段

描述

validate

检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到。

initialize

初始化构建状态,例如设置属性。

generate-sources

生成编译阶段需要包含的任何源码文件。

process-sources

处理源代码,例如,过滤任何值(filter any value)。

generate-resources

生成工程包中需要包含的资源文件。

process-resources

拷贝和处理资源文件到目的目录中,为打包阶段做准备。

compile

编译工程源码。

process-classes

处理编译生成的文件,例如 Java Class 字节码的加强和优化。

generate-test-sources

生成编译阶段需要包含的任何测试源代码。

process-test-sources

处理测试源代码,例如,过滤任何值(filter any values)。

test-compile

编译测试源代码到测试目的目录。

process-test-classes

处理测试代码文件编译后生成的文件。

test

使用适当的单元测试框架(例如JUnit)运行测试。

prepare-package

在真正打包之前,为准备打包执行任何必要的操作。

package

获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。

pre-integration-test

在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量。

integration-test

处理和部署必须的工程包到集成测试能够运行的环境中。

post-integration-test

在集成测试被执行后执行必要的操作。例如,清理环境。

verify

运行检查操作来验证工程包是有效的,并满足质量要求。

install

安装工程包到本地仓库中,该仓库可以作为本地其他工程的依赖。

deploy

拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

  • 当一个阶段通过 Maven 命令调用时,例如mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行。

Site生命周期

  • Maven Site 插件一般用来创建新的报告文档、部署站点等。
  • 包含以下阶段
    • pre-site:执行一些需要在生成站点文档之前完成的工作
    • site:生成项目的站点文档
    • post-site:执行一些需要生成站点文档之后完成的工作
    • site-deploy:将生成站点文档部署到特定的服务器上

Maven统一管理依赖的版本号

  • 假设如下的依赖:
代码语言:javascript
复制
<!-- SpringMVC -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>4.3.13.RELEASE</version>
	</dependency>

	<!-- Spring-JDBC,要和spring-webmvc的版本一致 -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jdbc</artifactId>
		<version>4.3.13.RELEASE</version>
	</dependency>
  • 那么当我们需要改变spring的依赖版本号为4.3.12.RELEASE,那么我们只有逐个改变version中的值,现在是两个依赖比较好改变的,如果要有很多个的话,那么难免会改错,因此我们需要使用一种方式统一管理依赖的版本号。我们可以使用<properties>标签来管理,新的配置文件如下:
    • properties中的标签体可以任意指定,如果需要引用定义的标签体中的内容,那么直接使用${标签体}即可
    • 此时我们要是改变版本,那么只需要改变<properties>中的版本即可
代码语言:javascript
复制
<!-- 使用properties管理版本号 -->
	<properties>
		<!-- 这里的标签体可以任意指定,后续只要使用${}引用标签体即可使用其中定义的内容 -->
		<spring-version>4.3.13.RELEASE</spring-version>
	</properties>
	
	<dependencies>
		<!-- SpringMVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<!-- version使用${} -->
			<version>${spring-version}</version>
		</dependency>

		<!-- Spring-JDBC,要和spring-webmvc的版本一致 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>
        
	</dependencies>

继承

  • 我们知道只有compile范围内的依赖才可以传递,但是对于testprovided中的依赖却是不可以传递的,那么必须在每个项目中都要添加依赖,此时肯定会出现每个项目中依赖版本不一致的情况,这样对于每个人的开发来说是比较困难的,因为不同版本的依赖使用的方式也不同,此时我们就需要统一管理这个版本了。
  • 下面我们以junit的版本控制为例

步骤

  • 创建一个父工程Hello-Parent,打包的方式为pom
  • Hello-Parent中的pom.xml文件中使用dependencyManagement管理版本,控制junit的版本依赖
代码语言:javascript
复制
<project 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/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.tedu</groupId>
  <artifactId>Hello-Parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
    
  <!-- 使用properties控制版本号 -->
  <properties>
  	<junit-version>4.12</junit-version>
  </properties>
  
  <!-- 使用dependencyManagement管理版本 -->
  <dependencyManagement>
  	
  	<dependencies>
  		<!-- Junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit-version}</version>
			<scope>test</scope>
		</dependency>
		
  	</dependencies>
  </dependencyManagement>
  
</project>
  • 在子工程中使用parent标签指定声明对父工程的引用
代码语言:javascript
复制
<parent>
	<groupId>cn.tedu</groupId>
	<artifactId>Hello-Parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<!-- 使用relativePath指定父工程的相对位置 -->
	<relativePath>../Hello-Parent</relativePath>
</parent>
  • 将子工程坐标和父工程坐标重复的地方删除,不删除也没关系
  • 在子工程中删除junitversion标签,表明是继承自父工程的版本,不需要指定
代码语言:javascript
复制
<!-- Junit -->
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
          <!--此时不需要指定version了,因为父工程中已经指定了-->
</dependency>
  • 子工程全部的配置
代码语言:javascript
复制
<project 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/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!-- 这里的groupId和父工程中的重复了,因此可以删除 
	<groupId>cn.tedu</groupId>-->
	<artifactId>Hello</artifactId>
	<!-- 这里的version版本也和父工程的重复了,因此可以删除
	<version>0.0.1-SNAPSHOT</version> -->
	
	<parent>
		<groupId>cn.tedu</groupId>
		<artifactId>Hello-Parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- 使用relativePath指定父工程的相对位置 -->
		<relativePath>../Hello-Parent</relativePath>
	</parent>
	
	<dependencies>
		<!-- Junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
            <!--不需要指定version-->
		</dependency>
	</dependencies>
</project>

聚合

  • 我们在开发项目的时候都是分模块开发的,此时如果想要使用maven安装这个项目的话,那么需要一个一个的安装,但是我们可以使用聚合的方式,可以实现一次性安装。并且安装还是有先后顺序的,一定要先安装父工程,否则将会找不到依赖信息,我们使用聚合的方式就没有先后安装的障碍了,maven会为我们自动的解决

步骤

  1. 创建一个maven工程,打包方式为pom,当然也是可以直接使用父工程
  2. 在pom.xml配置文件中配置module
  3. 详细的pom.xml如下:
代码语言:javascript
复制
<project 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/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.tedu</groupId>
  <artifactId>Hello-Manager</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  
  <!-- 继承父工程 -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>Hello-Parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- 使用relativePath指定父工程的相对位置 -->
		<relativePath>../Hello-Parent</relativePath>
	</parent>
  
  <!-- 使用聚合的方式 -->
  <modules>
  	<module>../Hello-Parent</module>
  	<module>../Hello</module>
  	<module>../HelloFriend</module>
  	<module>../MakeFriend</module>
  </modules>
  
</project>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Maven使用总结
    • 依赖范围
      • 依赖传递
        • 注意
      • 依赖排除
        • 依赖原则
          • 依赖路径最短优先原则
          • pom文件中申明顺序优先
          • 覆写优先
        • 生命周期
          • 生命周期调用的特点
          • clean生命周期
          • default生命周期
          • Site生命周期
        • Maven统一管理依赖的版本号
          • 继承
            • 步骤
          • 聚合
            • 步骤
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档