1、本地仓库?Maven到底有哪些仓库?它们什么关系?

Maven仓库:

本地仓库路径配置:

包查找路径:本地——>私服——>中央仓库,然后将查找到的jar同步到私服——>本地仓库

私服,就是公司内部局域网的一台服务器!当你的工程Project-A依赖别人的Project-B的接口,怎么做呢?没有Maven的时候,当然是copy Project-B jar到你的本地lib中引入,那么Maven的方式,很显然需要其他人把Project-B deploy到私服仓库中供你使用。因此私服中存储了本公司的内部专用的jar!不仅如此,私服还充当了中央仓库的镜像,说白了就是一个代理!

中央仓库:该仓库存储了互联网上的jar,由Maven团队来维护,地址是:http://repo1.maven.org/maven2/。

2、关于的使用

依赖管理

其实这个标签揭示了jar的查找坐标:groupIdartifactIdversion

一般而言,我们可以到私服上输入artifactId进行搜索,或者到http://search.maven.org/、http://mvnrepository.com/上进行查找确定坐标。

version分为开发版本(Snapshot)和发布版本(Release),那么为什么要分呢?

在实际开发中,我们经常遇到这样的场景,比如A服务依赖于B服务,A和B同时开发,B在开发中发现了BUG,修改后,将版本由1.0升级为2.0,那么A必须也跟着在POM.XML中进行版本升级。过了几天后,B又发现了问题,进行修改后升级版本发布,然后通知A进行升级...可以说这是开发过程中的版本不稳定导致了这样的问题。

Maven,已经替我们想好了解决方案,就是使用Snapshot版本,在开发过程中B发布的版本标志为Snapshot版本,A进行依赖的时候选择Snapshot版本,那么每次B发布的话,会在私服仓库中,形成带有时间戳的Snapshot版本,而A构建的时候会自动下载B最新时间戳的Snapshot版本!

Snapshot

3、既然Maven进行了依赖管理,为什么还会出现依赖冲突?处理依赖冲突的手段是?

依赖的版本?

首先来说,对于Maven而言,同一个groupId同一个artifactId下,只能使用一个version

根据上图的依赖顺序,将使用1.2版本的jar。 后面的版本覆盖前面的版本号

现在,我们可以思考下了,比如工程中需要引入A、B,而A依赖1.0版本的C,B依赖2.0版本的C,那么问题来了,C使用的版本将由引入A、B的顺序而定?这显然不靠谱!如果A的依赖写在B的依赖后面,将意味着最后引入的是1.0版本的C,很可能在运行阶段出现类(ClassNotFoundException)、方法(NoSuchMethodError)jar冲突,找不到的错误(因为B使用的是高版本的C)!

这里其实涉及到了2个概念:依赖传递(transitive)、Maven的最近依赖策略。

依赖传递:如果A依赖B,B依赖C,那么引入A,意味着B和C都会被引入。

Maven的最近依赖策略:如果一个项目依赖相同的groupId、artifactId的多个版本,那么在依赖树(mvn dependency:tree)中离项目最近的那个版本将会被使用。(从这里可以看出Maven是不是有点小问题呢?能不能选择高版本的进行依赖么?据了解,Gradle就是version+策略)

现在,我们可以想想如何处理依赖冲突呢?

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

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

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

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

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

使用

4、引入依赖的最佳实践,提前发现问题!

在工程中,我们避免不了需要加一些依赖,也许加了依赖后运行时才发现存在依赖冲突在去解决,似乎有点晚!那么能不能提前发现问题呢?

如果我们新加入一个依赖的话,那么先通过mvn dependency:tree命令形成依赖树,看看我们新加入的依赖,是否存在传递依赖,传递依赖中是否和依赖树中的版本存在冲突,如果存在多个版本冲突,利用上文的方式进行解决!

5、Maven规范化目录结构

这里需要注意2点:

第一:src/main下内容最终会打包到Jar/War中,而src/test下是测试内容,并不会打包进去。

第二:src/main/resources中的资源文件会COPY至目标目录,这是Maven的默认生命周期中的一个规定动作。(想一想,hibernate/mybatis的映射XML需要放入resources下,而不能在放在其他地方了)

6、Maven的生命周期

Maven生命周期:

我们只需要注意一点:执行后面的命令时,前面的命令自动得到执行。

实际上,我们最常用的就是这么几个:

clean:有问题,多清理!

package:打成Jar or War包,会自动进行clean+compile

install:将本地工程Jar上传到本地仓库

deploy:上传到私服

7、关于scope依赖范围 参见 MAVEN(一)Scope

既然,Maven的生命周期存在编译、测试、运行这些过程,那么显然有些依赖只用于测试,比如junit;有些依赖编译用不到,只有运行的时候才能用到,比如mysql的驱动包在编译期就用不到(编译期用的是JDBC接口),而是在运行时用到的;还有些依赖,编译期要用到,而运行期不需要提供,因为有些容器已经提供了,比如servlet-api在tomcat中已经提供了,我们只需要的是编译期提供而已。

总结来说:

compile:默认的scope,运行期有效,需要打入包中。

provided:编译期有效,运行期不需要提供,不会打入包中。

runtime:编译不需要,在运行期有效,需要导入包中。(接口与实现分离)

test:测试需要,不会打入包中。

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

MAVEN(二)的更多相关文章

  1. maven(二) maven项目构建ssh工程(父工程与子模块的拆分与聚合)

    前一节我们明白了maven是个什么玩意,这一节就来讲讲他的一个重要的应用场景,也就是通过maven将一个ssh项目分割为不同的几个部分独立开发,很重要,加油 --WH 一.maven父工程与子模块的拆 ...

  2. 转帖:maven(二) maven项目构建ssh工程(父工程与子模块的拆分与聚合)

    出处:http://www.cnblogs.com/whgk/p/7121336.html 前一节我们明白了maven是个什么玩意,这一节就来讲讲他的一个重要的应用场景,也就是通过maven将一个ss ...

  3. Maven(二)使用eclipse创建maven多模块项目

    maven作为一种自动化构建工具,在现在的企业应用开发中运用非常普遍. 企业项目一般都比较大,多采用maven管理的多模块项目,下面直接上创建步骤 一.创建一个maven项目

  4. Ubuntu 14.04 Android 使用Maven二 创建自己的Mavenproject

    依据https://code.google.com/p/maven-android-plugin/wiki/GettingStarted 介绍,有两种方法能够创建Mavenproject. 第一种方法 ...

  5. Maven二

    1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...

  6. maven(二):创建一个可用的maven项目,完整过程

    环境:eclipse4.5 (内置maven插件) 创建maven项目 文件菜单--新建--其他-- maven project 下一步 选择web 结构 group id:  指项目在maven本地 ...

  7. maven(二)

    1.1     Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2     Maven安装部署配置 1.3     Maven的仓库 ...

  8. maven(二)基于intellij idea搭建ssm的maven项目结构

    项目配置文件整合步骤 1.这里使用maven来引入项目所需要的jar包,所以也就不需要手动来管理jar包了. pom.xml 配置模板如下: <project xmlns="http: ...

  9. maven(二)基于intellij idea搭建maven项目

    搭建步骤: 1.File -> New Module,进入创建项目窗口. 接着下一步,这里需要注在Properties中添加一个参数 archetypeCatalog=internal,不加这个 ...

  10. maven(二)创建一个maven的web项目中解决Cannot change version of project facet Dynamic web module to 2.5

    我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一 ...

随机推荐

  1. C++中的平方、开方、绝对值怎么计算

    #include <math.h> //平方 pow() ,);// 4的平方=16 //开方 ,0.5);// 4的平方根=2 );// 4的平方根=2 //整数绝对值 int c = ...

  2. Myeclipse10 安装 破解 激活(含安装包,激活软件 免费)

    参考博客: https://www.cnblogs.com/gzhnan/articles/9536275.html 注意 安装完成之后一定不要点 Launch Myeclipse 下载地址: htt ...

  3. zabbix (6) 为主机添加监控项,触发器,动作

    先了解一下zabbix的相关概念 监控项(iterms):一个具体的指标,比如某个人的体重. 键(key):通过定义(自定义或者zabbix自带)的key获取相应指标的具体值,比如这个人的体重50斤 ...

  4. spark错误记录总结

    1.执行spark-submit时出错 执行任务如下: # ./spark-submit --class org.apache.spark.examples.SparkPi /hadoop/spark ...

  5. 线程wait和notify方法的demo详解

    wait和notify都是针对某个线程而言的: package com.roocon.thread.t1; public class NewThread implements Runnable { @ ...

  6. js的一些兼容性易错的的问题

    一.属性相关 我们通常把特征(attribute)和属性(property)统称为属性,但是他们确实是不同的概念,特征(attribute)会表现在HTML文本中,对特征的修改一定会表现在元素的out ...

  7. Flutter移动电商实战 --(48)详细页_详情和评论的切换

    增加切换的效果,我们主要是修改这个地方 这样我们的评论的内容就显示出来了 最终代码 details_web.dart import 'package:flutter/material.dart'; i ...

  8. ISO/IEC 9899:2011 条款5——5.2.3 信号与中断

    5.2.3 信号与中断 1.函数应该被设计为它们可以被一个信号在任一时刻打断,或是被一个信号处理所调用,或是两者都发生,对于初期不发生改变,但仍然处于活动状态,调用的控制流(在中断之后),函数返回值, ...

  9. javascript的promise

  10. jpeglib.h jerror.h No such file or directory 以及 SDL/SDL.h: 没有那个文件

    1. error: jpeglib.h jerror.h No such file or directory 没有那个文件或目录 jpeg.cc:19:21:error: jpeglib.h: 没有那 ...