首页 文章
取消

Maven的重要知识点

初学J2EE时都会学习Maven,但工作后未必需要自己去维护依赖,导致对Maven的认知还仅限于追加dependency标签。工作几年后再系统性地回顾Maven,发现有些知识点至关重要,它们能帮助自己维护依赖时做到有的放矢。

依赖关系

引入依赖前,我们需要清楚应该采用何种依赖关系,虽然大部分依赖的scope都会设置为complie,但还有一些依赖需要设置为其它类型,一旦设置错误可能会出现BUG。举例来说,如果servlet-apiscopecomplie,那么servlet-api就会被打到项目的jar里,进而导致与Tomcat内置的servlet-api产生冲突。

Maven定义了几种依赖关系,分别是compiletestruntimeprovided

scope

说明

示例

compile

编译时需要用到该jar包(默认)

commons-logging

test

编译Test时需要用到该jar包

junit

runtime

编译时不需要,但运行时需要用到

mysql(mysql驱动在编译时并不需要)

provided

编译时需要用到,但运行时由JDK或某个服务器提供

servlet-api(Servlet服务器内置了相关的jar,所以运行时不需要,但是写servlet时需要继承HttpServlet,所以编译时需要

SNAPSHOT

对于某个依赖,Maven只需要3个变量即可唯一确定某个jar包:

  • groupId:属于组织的名称,类似Java的包名

  • artifactId:该jar包自身的名称,类似Java的类名

  • version:该jar包的版本

通过上述3个变量,即可唯一确定某个jar包。Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改,修改已发布jar包的唯一方法是发布一个新版本。因此,某个jar包一旦被Maven下载过,即可永久地安全缓存在本地。

但是对于处于开发中的依赖,不可能每次修改jar都发布一个新版本,所以需要一个机制来实现不用发布新版本,Maven也能拉取到依赖的最新版本,这个机制就是SNAPSHOT(快照)<version>-SNAPSHOT结尾的版本号会被Maven视为开发版本,开发版本每次都会重复下载。

依赖管理

引入依赖时可能需要考虑一些额外情况,此时就要用到<dependency>下的一些子标签。

exclusions

实际项目中会引入大量的依赖,极有可能出现重复依赖的情况,例如A依赖C,B也依赖C,这两个C也许版本并不相同,此时就需要在A或B的<dependency>中声明<exclusions>来排除掉依赖C。

除了避免重复依赖的问题,<exclusions>的意义还在于:我们想要自己引入某个依赖B,但是依赖A本身也引入了B,这就导致B被依赖传递到项目中了,我们不想要这个被传递过来的B,那么就需要在A中<exclusions>掉B,然后自己声明一个B来引入。

optional

<optional>true</optional>表示这个依赖是可选的,也就是说,它不会传递给依赖本项目的其他项目,这样可以避免不必要的依赖传递和冲突。举例来说,如果项目A使用的日志实现框架是log4j,但是依赖A的项目B想用logback,那么A就应该把自己的log4j设置为<optional>true</optional>,这样B在引入A时,就不会把log4j也引入了。

Reference

廖雪峰的官方网站

Maven 依赖管理 | 菜鸟教程