文章来自:https://www.jianshu.com/p/e224a6dc8f20和https://www.jianshu.com/p/20b39ab6a88c

Maven出现之前

  jar包默认都是放到/lib目录下,而如果要新增一个jar包,就需要到处找相应的jar包,如果这个jar包又依赖其他jar包,就比较坑爹了,

网上很多都需要积分或者VIP。或者是如果新建一个项目,我们需要把之前的jar拷贝过去,总之,jar包管理很麻烦

直到Maven出现

  上述的关于jar包的各种闹心的问题都能迎刃而解,而我们只需要关心功能和业务

Maven的功能有哪些

  1、工程的创建、测试

  2、依赖管理

  3、仓库管理

  4、自动化部署

  。。。。

仓库

仓库就是一个位置,可以存储jar包、library jar、插件任何其他的工程指定的文件。

1、本地仓库

  第一次运行maven命令在本地创建的一个文件夹,会把依赖的jar包放到本地仓库,避免每次构建都引用远程仓库的依赖文件

默认地址:${user.home}/.m2/repository目录下。要修改默认位置,只要在 settings.xml文件中定义另一个路径即可,例如:

<localRepository>/anotherDirectory/.m2/respository</localRepository>

2、远程仓库

  Maven的远程仓库可以是任何其他类型的存储库,可通过各种协议,例如 file://http:// 来访问。这些存储库可以是由第三方

提供的可供下载的远程仓库,

例如Maven 的中央仓库(central repository):

  repo.maven.apache.org/maven2

  uk.maven.org/maven2

也可以是在公司内的FTP服务器或HTTP服务器上设置的内部存储库,用于在开发团队和发布之间共享私有的 artifacts。

中央仓库

  Maven 的中央仓库是 Maven 社区维护的,里面包含了大量常用的库,我们可以直接引用,但是前提是我们的项目能够访问外网。

maven仓库地址:https://mvnrepository.com/

私有仓库

  除了 Maven 的中央仓库外,还有一种就是私有仓库,本人公司使用的就是私有仓库,因为在内网使用。

Maven依赖查找jar包顺序:

  本地仓库--->私有仓库--->配置的中央仓库--->报错。这中间只要在某一个仓库中找到了就会返回了,除非仓库中有更新的版本,或者是snapshot版本。

Maven远程仓库配置:

<profiles><profile><id>central</id><repositories><repository><id>Central</id><name>Central</name><url>http://repo.maven.apache.org/maven2/</url></repository></repositories></profile>
</profiles>
<activeProfiles><activeProfile>central</activeProfile>
</activeProfiles>

镜像

  Mirror相当于代理,我们配置镜像一般为了网速考虑

可以在Maven中配置该镜像来替代中央仓库。在settings.xml中配置如下代码:

<mirrors>
<mirror><id>maven.net.cn</id><mirrorOf>maven.net.cn</mirrorOf><name>one of the central mirrors in china</name><url>http://maven.net.cn/content/groups/public/</url>
</mirror>
</mirrors>

生命周期

  Maven有三个内置的构建生命周期: defaultcleansite。每个生命周期都由一系列的阶段所构成

阶段的执行是按顺序的,一个阶段执行完成之后才会执行下一个阶段。

比如我们执行了一个如下的指令:

mvn install

实际会执行 install 阶段之前的所有阶段,然后才会执行 install 阶段本身。

常用:

  1、clean:有问题就清理

  2、package:打成jar或war包,自动进行clean和compile

  3、install:将本地jar上传到本地仓库

  4、deploy:将jar包上传到私服

PS:当我们的项目是多模块的,我们在最顶层执行该指令时,Maven 会遍历每一个子模块,依次执行所有的阶段。

坐标

groupId:表示一个团体,可以是公司、组织等

artifactId:表示团体下的某个项目

version:表示某个项目的版本号

他们之间的关系是一对多的,即每个团体下可以有多个项目,每个项目可以有多个版本号,可以用下面这张图来表示:

Scope依赖范围

Maven生命周期存在编译、测试、运行的过程,例如Junit只用于测试,MySQL驱动在编译期用不到,只是在运行期才使用,编译期用到的是JDBC接口,Tomcat

的servlet-api只在编译器用到,而运行期间不需要提供,因为有些容器已经提供

scope:

  1、compile:默认的scope,运行期间有效,需要打到jar包

  2、provided:编译期有效,运行期不提供,不打到jar包

  3、runtime:编译期不需要,运行期有效,需要打到jar包(接口和实现分离)

  4、test:测试需要,不打到jar包

  5、system:非本地仓库引用、存在系统的某个路径下的jar包(一般不使用)

依赖

  Maven 核心特点之一是依赖管理。一旦我们开始处理多模块工程(包含数百个子模块或者子工程)的时候,模块间的依赖关系就变得非常复杂,

管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。

1、依赖传递

  如果引入一个jar包,这个jar包又依赖另一个jar包,项目编译时,maven会把直接引用和间接引用的jar包都下载到本地仓库。但是依赖传递有时又很麻烦,

因为很可能会造成依赖的冲突。

2、依赖冲突

  当同一个项目中由于不同的jar包依赖了相同的jar包,此时就会发生依赖冲突的情况,如下图所示:

  当项目中依赖了a和c,而a和c都依赖了b,这时就造成了冲突。为了避免冲突的产生,Maven 使用了两种策略来解决冲突,分别是短路优先

声明优先

  依赖冲突不是指引入多个不同version的相同jar包,这种冲突,只能手动解决

  在IDEA中,可以在pom.xml中,右键Maven--->Show Dependency,直接通过Ctrl+O查找具体某个jar,在pom文件中是否存在多个依赖

原文对依赖冲突有很详细的解释,原文地址在文章最上面

2.1、短路优先

  短路优先的意识是,从项目一直到最终依赖的jar的距离,哪个距离短就依赖哪个,距离长的将被忽略掉。例如下图所示:

声明优先

  声明优先的意思是,通过jar包声明的顺序来决定使用哪个,最先声明的jar包总是被选中,后声明的jar包则会被忽略,如下图所示:

依赖排除

  如果我们只想引用我们直接依赖的jar包,而不想把间接依赖的jar包也引入的话,那可以使用依赖排除的方式,将间接引用的jar包排除掉,

如下面的配置所示:

<exclusions><exclusion><groupId>excluded.groupId</groupId><artifactId>excluded-artifactId</artifactId></exclusion>
</exclusions>

引入依赖的最佳实践

我们再添加依赖的时候,可能在运行的时候才发现依赖冲突,而实际上可以提前就发现问题

加入一个新的依赖的时候,先通过mvn dependency:tree形成依赖树,查看是否存在传递依赖,传递依赖中是否和依赖树中版本行程冲突,这时候可以提前解决

解决方案:

  1、要使用哪个版本,我们是清楚的,那么能不能不管如何依赖传递,都可以进行版本锁定呢?

使用<dependencyManagement>  [这种主要用于子模块的版本一致性中]

  2、在依赖传递中,能不能去掉我们不想依赖的?

使用<exclusions> [在实际中我们可以在IDEA中直接利用插件帮助我们生成]

  3、既然是最近依赖策略,那么我们就直接使用显式依赖指定版本,那不就是最靠近项目的么?

使用<dependency>

依赖管理

聚合

  将多个项目同时运行就称为聚合,如下就是一个多模块的项目:

<packaging>pom</packaging>
<modules><module>module-1</module><module>module-2</module><module>module-3</module></modules>

聚合的优势在于可以在一个地方编译多个pom文件。

PS:聚合时packaging必须要是pom

继承

  跟java类的继承类似,Maven 的继承特性也会继承父pom中的依赖,假设我们定义了一个父pom:

<groupId>com.houyi</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version><dependencyManagement><dependencies><dependency><groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope></dependency><dependency><groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version></dependency></dependencies>
</dependencyManagement>

然后在子pom中引入这个父pom:

<!-- 指定parent,说明是从哪个pom继承 -->
<parent><groupId>com.houyi</groupId> <artifactId>maven-parent</artifactId> <version>0.0.1-SNAPSHOT</version><!-- 指定相对路径 --> <relativePath>../maven-parent</relativePath>
</parent><!-- 只需要指明groupId + artifactId,就可以到父pom找到了,无需指明版本 -->
<dependencies><dependency><groupId>junit</groupId> <artifactId>junit</artifactId> </dependency><dependency><groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
</dependencies>

  使用dependencyManagement,可对依赖进行管理。子类只要不引用这个里面写的groupId + artifactId,则不会添加依赖,这样防止造成重复加了包:

如果不使用dependencyManagement,那么只要写了dependency,子pom中会全部添加到依赖中,而其中很多包可能都用不上。

插件

  插件是 Maven 的核心,所有执行的操作都是基于插件来完成的。

  为了让一个插件中可以实现众多的相类似的功能,Maven 为插件设定了目标,一个插件中有可能有多个目标。其实生命周期中的每个阶段都是

由插件的一个具体目标来执行的

  例如可以用下面的方式配置一个插件:

<build><plugins><plugin> <groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId> <version>2.2.1</version><!-- 配置执行 --><executions><execution><phase>package</phase><goals><goal>jar-no-fork</goal></goals></execution></executions></plugin></plugins>
</build>

  配置目标 goal 的目的是:这样在执行 mvn package 的时候,就会自动执行 mvn source:jar-no-fork了,jar-no-fork这个目标是用来进行源码打包的。

  除了可以在build元素中配置插件,当然也可以在parent项目中,用pluginManagement来配置,然后在子项目继承即可使用。

PS:

  通过插件我们可以做很多事,比如通过mybatis-generator 我们可以生成很多DAO层的代码,再配合通用Mapper+lombok使用的话就可以使你的代码

非常简洁,绝对的生产力工具!

指令

下面列举一些常用的 maven 指令:

指令参数

  上面列举的只是比较通用的命令,其实很多命令都可以携带参数以执行更精准的任务。

Maven命令可携带的参数类型如下:

-D 传入属性参数

比如命令:mvn package -Dmaven.test.skip=true

-D开头,将 maven.test.skip 的值设为 true ,就是告诉maven打包的时候跳过单元测试。

-P 使用指定的Profile配置

  比如项目开发需要有多个环境,一般为开发,测试,预发,正式4个环境,在pom.xml中的配置如下:

<profiles><profile><id>dev</id><properties><env>dev</env></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>qa</id><properties><env>qa</env></properties></profile><profile><id>pre</id><properties><env>pre</env></properties></profile><profile><id>prod</id><properties><env>prod</env></properties></profile>
</profiles>...<build><filters><filter>config/${env}.properties</filter></filters><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources>
</build>

  profiles定义了各个环境的变量idfilters中定义了变量配置文件的地址,其中地址中的环境变量就是上面profile中定义的值,resources中是定义

哪些目录下的文件会被配置文件中定义的变量替换。

  通过maven可以实现按不同环境进行打包部署,命令为:

mvn package -P dev

其中 dev 为环境的变量id,代表使用Id为 devprofile

-e 显示maven运行出错的信息

-o 离线执行命令,即不去远程仓库更新包

-X 显示maven允许的debug信息

-U 强制去远程更新snapshot的插件或依赖,默认每天只更新一次

举个例子

将自己的jar包部署到远程仓库去,可以使用 deploy 指令:

mvn deploy:deploy-file -DgroupId=<group-id> \-DartifactId=<artifact-id> \-Dversion=<version> \-Dpackaging=<type-of-packaging> \-Dfile=<path-to-file> \-DrepositoryId=<id-to-map-on-server-section-of-settings.xml> \-Durl=<url-of-the-repository-to-deploy>

最后说下我们为什么要学习maven,大概可以收获这些好处吧:

  • 提高自己的生产力
  • 更好的管理项目中的jar包
  • 自己开发的jar包可以共享给别人
  • 遇到jar包冲突问题可以不求人

。。。

转载于:https://www.cnblogs.com/huigelaile/p/10910426.html

日常开发需要掌握的Maven知识相关推荐

  1. Android开发需要了解的 IM 知识

    引言 即便在通讯如此发达的今天,IM 也依然是诸多场景下非常重要的基础能力.因此做为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题.本文以一个Android开发的角度来讲述I ...

  2. 如何使用Arthas提高日常开发效率?

    简介: 1. Arthas有什么功能,怎么用,请看:Arthas使用手册 2. Arthas命令比较复杂,一个帮助生成命令的IDEA插件:arthas idea plugin 使用文档 3. 基于Ar ...

  3. 推荐10个实用的日常开发和写作必备工具

    前言 分享几个我日常开发或写作过程中经常用到的工具软件和网站,看看哪些是你没用过的,喜欢的话可以点赞和收藏哦-. 1. 截图工具(snipaste) 官网地址 snipaste是一款截图+贴图工具,按 ...

  4. 【Unity3D日常开发】Unity3D中实现计时器工具类-正计时、倒计时、暂停计时、加速计时

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  5. Android日常开发收集的Tips

    Android日常开发收集的Tips 1. 时间戳转时间: 要注意时间戳的位数,10位的是秒级别的,13位的是毫秒级别的, 因此,在转化为时间中,也有稍微的区别. // 10位的秒级别的时间戳long ...

  6. 【Unity3D日常开发】Unity3D打包PC窗口化打包设置

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  7. 【Unity3D日常开发】Unity3D中打包WEBGL后读取本地文件数据

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  8. 日常安排php,PHP日常开发小技巧

    PHP日常开发小技巧 导语:PHP语言中,如果你懂得一些开发技巧,那么对你学PHP,会有很大的帮助.下面的是百分网小编为大家整理的PHP日常开发小技巧,希望对你能有所帮助. PHP批量取得checkb ...

  9. Java日常开发的21个坑,你踩过几个?

    前言 最近看了极客时间的<Java业务开发常见错误100例>,再结合平时踩的一些代码坑,写写总结,希望对大家有帮助,感谢阅读~ 1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空 ...

最新文章

  1. 安卓开发8-WebView支持文件上传
  2. google svn 服务器申请 使用
  3. 只用最适合的! 全面对比主流 .NET 报表控件:水晶报表、FastReport、ActiveReports 和 Stimulsoft...
  4. java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContextAware
  5. 11月碎碎念-谈职场礼貌
  6. Where do SAP CRM HANA Live Querys come from
  7. 国家计算机二级access考试试题,全国计算机二级access试题及答案
  8. Python:PDF文件转图像
  9. Chaos Control for Mac(GTD计划任务管理工具)
  10. struts2之日期类型转换
  11. 问题解决逻辑:深度和广度谁应该优先?
  12. CryEngine GameLaucher 和Editor
  13. 从五个方面来讲一下平面设计颜色搭配知识——黎乙丙
  14. 零基础的人怎么备考二建
  15. 如何免费将excel表格转换成Word文档?
  16. 手把手教你搭建自己的 AV1 Analyzer
  17. 背景与小鸟--FlappyBird游戏开发教程之二
  18. 37岁京东程序员“被猝死”,当事人辟谣:已报警
  19. 老板:你们和外包有什么区别?
  20. 基础编程练习题(二)

热门文章

  1. 大一java怎么学好_是否应该学习第二门语言,学那个比较合适。
  2. 系统搜索资源就停止服务器,SQL Server (MSSQLSERVER) 服务启动不了,系统日志显示由于下列服务特定错误而终止: 找不到映像文件中指定的资源名。...
  3. Ghost Blog
  4. javascript arguments(转)
  5. docker安装mysql以及设置navicat远程访问
  6. 难得一见的DIY针孔相机
  7. Kubernetes中的nodePort,targetPort,port的区别和意义(转)
  8. webgame 上线版本控制
  9. 一个对Winsock完成端口模型封装的类
  10. 新手老问题---------跨线程的控件访问