Maven学习笔记

之前匆匆学了maven,没有记好笔记,结果实习中挺多问题还是得百度解决,今天就系统的回顾一下maven。

 

一、为什么要学Maven?

统一管理依赖

我们现在的项目可能要用到很多框架,项目中依赖的jar包也越来越多,而且jar包之间的依赖关系也很复杂,使用maven可以自动的下载这些jar包并引用、可以很好的自动管理jar包之间的依赖,程序员可以省去很多工作。

进行项目构建

可以简化项目的构建过程。当我们使用IDEA进行开发时,项目的构建都是IDEA进行自动完成的,但是如果脱离了IDE就要用专业的构建工具来完成。

什么是项目的构建? 

使用原材料生产出一个产品的过程。

原材料:Java源代码、配置文件、图片等我们开发的东西。

产品:一个可以运行在服务器上的项目。

构建过程包含的主要的环节:

  • 清理:删除上一次构建的结果,为下一次构建做好准备
  • 编译:Java 源程序编译成 *.class 字节码文件
  • 测试:运行提前准备好的测试程序
  • 报告:针对刚才测试的结果生成一个全面的信息
  • 打包
    • Java工程:jar包
    • Web工程:war包
  • 安装:把一个 Maven 工程经过打包操作生成的 jar 包或 war 包存入 Maven 仓库
  • 部署
    • 部署 jar 包:把一个 jar 包部署到 Nexus 私服服务器上
    • 部署 war 包:借助相关 Maven 插件(例如 cargo),将 war 包部署到 Tomcat 服务器上

idea工具maven的Lifecycle功能讲解

clean:用于清除上次构建生成的所有文件,一般在构建前执行。执行该命令会删除项目路径下的target文件,但是不会删除本地的maven仓库已经生成的jar文件。

mvn clean

validate:验证,验证工程是否正确,所需的信息是否完整。

compile:编译,编译Java源代码成class字节码文件,编译后的class文件会存在target目录下的classes目录中。

主程序编译:mvn compile

测试程序编译:mvn test-compile

主体程序编译结果存放的目录:target/classes

测试程序编译结果存放的目录:target/test-classes

test:测试,用合适的测试框架来进行测试,测试compile中编译出来的代码,测试的东西一般不加包和部署。

mvn test

测试的报告存放的目录:target/surefire-reports

package:打包,将工程文件打包为指定的格式,例如JAR,WAR等(项目的pom文件中的packing标签指定打包类型)。存到target目录,并且拥有compile命令的功能进行编译。如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错,因为找不到所依赖的b项目,说明a项目在本地仓库是没有找到它所依赖的b项目,这时就用到install命令。

verify:验证,检查package是否有效、符合标准。

install:安装,将项目的包安装到本地仓库中(本地仓库中的目录就是项目的坐标),好让其他项目引用。这个命令包含package,也会将项目打包成jar包或war包到本地仓库中。另外,安装操作还会将 pom.xml 文件转换为 XXX.pom 文件一起存入本地仓库。所以我们在 Maven 的本地仓库中想看一个项目的原始的 pom.xml 文件时,查看对应 XXX.pom 文件即可。

site:站点,生成项目的站点文档,生成的网站是在项目的“target/site”文件夹。

deploy:部署,复制最终的包至远程仓库,共享给其它开发人员和项目。

二、如何学好maven

maven安装

安装很简单,就不说了,主要记录一下maven目录下的conf/settings.xml设置文件

指定本地仓库位置

本地仓库默认值:用户家目录/.m2/repository。由于本地仓库的默认位置是在用户的家目录下,而家目录往往是在 C 盘,也就是系统盘。将来 Maven 仓库中 jar 包越来越多,仓库体积越来越大,可能会拖慢 C 盘运行速度,影响系统性能。所以建议将 Maven 的本地仓库放在其他盘符下。

<localRepository>D:\maven-repository</localRepository>

配置阿里云提供的镜像仓库

项目依赖的jar包如果本地仓库中没有,就会远程仓库中找,下载 jar 包默认访问境外的中央仓库,而国外网站速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让 Maven 下载 jar 包的时候速度更快。配置的方式是:

    <mirror>
		<id>nexus-aliyun</id>
		<mirrorOf>central</mirrorOf>
		<name>Nexus aliyun</name>
		<url>http://maven.aliyun.com/nexus/content/groups/public</url>
	</mirror>

配置jdk版本

在settings.xml文件中设置会在所有maven项目中都生效,在pom文件中的配置只对当前项目有效。

	<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>

maven的工作机制

在项目的pom文件中定义好依赖的坐标后,先到本地仓库中找有没有,如果没有的话,就到私服中找,如果私服有则直接下载到本地仓库中用,反之则到远程仓库中下载,jar包下载后缓存在私服中(方便使用),最后都将jar包保存到本地仓库中使用。

maven的私服

maven的私有服务器,称为私服,是一种特殊的远程仓库,一般在公司中会自己的局域网内搭建自己的私服。

因为公司中一般会有很多人同时在开发一些项目,如果每个人都去远程仓库下载依赖,那么网络负载就会比较大, 在自己的局域网内搭建了私服,然后常用的依赖上传到私服中,下载访问的速度肯定比较快(提高jar包下载速度)。

如何配置私服:

    <!--镜像库nexus_coracle 和第三方库thirdparty  kevin 20180719-->
    <repositories>
        <repository>
            <id>nexus_coracle</id>
            <name>coracle private nexus</name>
            <url>http://xxx:7081/nexus/content/groups/public</url>
        </repository>
        <repository>
            <id>thirdparty</id>
            <name>Repository for thirdparty</name>
            <url>http://xxx:7081/nexus/content/repositories/thirdparty</url>
        </repository>
    </repositories>

maven依赖的范围

标签的位置:dependencies/dependency/scope

范围可选值:compile/test/provided/system/runtime/import

默认值:compile

main目录(空间)test目录(空间)开发过程(时间)部署到服务器(时间)
有效有效有效有效compile
无效有效有效无效test
main目录(空间)test目录(空间)开发过程(时间)部署到服务器(时间)
有效有效有效有效compile
有效有效有效有效provided

总结:

compile:通常使用的第三方框架的 jar 包,项目在实际运行时要用到的 jar 包都是以 compile 范围进行依赖的,就是需要参与部署到服务器上的。比如 SSM 框架所需jar包。

test:测试过程中使用的 jar 包,以 test 范围依赖进来,也不会打包进去,不参与部署。比如 junit。

provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servlet-api、jsp-api,这个服务器上已经有了,tomcat服务器本身里面就有了。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”

maven依赖的传递性

在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。

  • B 依赖 C 时使用 compile 范围:可以传递
  • B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

maven依赖冲突的排除

当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。

A项目依赖了B(B依赖了X-1.0),A项目也依赖了C(C依赖了X-2.0),如果X-都能传递到C的话,这样两个X-就会冲突,所以需要排除掉一个,解决包冲突。

<dependency>
	<groupId>com.atguigu.maven</groupId>
	<artifactId>pro01-maven-java</artifactId>
	<version>1.0-SNAPSHOT</version>
	<scope>compile</scope>
	<!-- 使用excludes标签配置依赖的排除	-->
	<exclusions>
		<!-- 在exclude标签中配置一个具体的排除 -->
		<exclusion>
			<!-- 指定要排除的依赖的坐标(不需要写version) -->
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>

maven的继承

Maven工程之间,A 工程继承 B 工程

  • B 工程:父工程
  • A 工程:子工程

本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。

意义:

 在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。

一个项目比较大的,通常要分成好几个模块,每个模块都会维护自己的依赖信息,有些依赖可能都是一样的,使用继承可以统一依赖的版本信息,统一依赖的最优版本组合,通过父工程统一管理维护依赖的信息的组合,可以保证依赖使用的准确性。

  <groupId>com.atguigu.maven</groupId>
  <artifactId>pro03-maven-parent</artifactId>
  <version>1.0-SNAPSHOT</version>

  <!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
  <packaging>pom</packaging>

  <!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
	</dependencies>
</dependencyManagement>
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
	<!-- 父工程的坐标 -->
	<groupId>com.atguigu.maven</groupId>
	<artifactId>pro03-maven-parent</artifactId>
	<version>1.0-SNAPSHOT</version>
</parent>

<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->

<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。	-->
<!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-expression</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-aop</artifactId>
	</dependency>
</dependencies>

编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。

如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

躺着听Jay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值