本篇我们来说一说maven依赖管理的坐标和scope属性。
maven坐标
首先我们在本地建了一个maven项目,目录结构如下:
pom文件的内容如下:
<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>com.maven</groupId>
<!--构件名称-->
<artifactId>Hello</artifactId>
<!--版本号-->
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<!--添加依赖的jar包-->
<dependencies>
<!--项目要使用到junit的jar包,所以在这里添加junit的jar包的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<!--依赖范围-->
<scope>test</scope>
</dependency>
</dependencies>
</project>
maven使用groupId、artifactId、version三个属性就可以唯一的标识一个资源,接下来我们使用mvn install命令,打包部署到本地仓库。从上一篇我们知道,mvn install会执行以下动作:
(1)编译,把Java 源程序编译成 class 字节码文件。
(2)打包(jar等)到本项目的target下。
(3)把target下打的包(jar等)安装到本地仓库,可以供其他项目使用。
结果如下图所示:
fp:repositoy是我们的本地仓库,上图可以看出,maven已经把我们的项目打包成功并安装在本地仓库,那如果其他的maven项目想使用我们的jar怎么办?这就是需要maven坐标来唯一的定位我们项目资源的位置。从上图可以看出,groupId就是(包名)+artifactId是(构件名称)+version(版本号)三个属性就可以唯一的标识一个资源。而jar包的命名规则是artifactId是(构件名称)+version(版本号)。
依赖范围 scope
- compile
默认scope就是compile,属于强依赖,参与项目的编译、测试、运行阶段,打包时候,也会被打包进去。
- test
仅参与测试相关的内容,包括测试用例的编译和执行,比如最常用的junit类,打包时候不会被打包进去。
- runtime
该依赖仅参与运行周期的使用,比如JDBC类库,一般这种类库都是接口与实现相分离的类库,在编译时候仅依赖相关的接口,具体运行时候,才需要具体的mysql、oracle等驱动程序。打包时候会被打包进去。
- provided
该依赖表示,由运行环境提供,最典型的就是tomcat容器相关的类如servlet等,该依赖可以参与编译、测试和运行等周期,但不会被打包进去。
- system
和provided类似,只是提供的环境是系统,从本地系统中提取,需要和systemPath属性配合使用。
- import
import只能在dependencyManagement属性内使用,并且需要配合属性type=pom,用于解决maven单继承问题。
在parent模块中,dependencyManagement中预定义太多的依赖,为了避免造成pom文件过长可以使用import scope导入相关依赖,然后子模块来决定是否继承。体现了单一职责设计原则。
实践
下面我们就拿compile和test来测试。
首先使用 命令快速创建web项目。
mvn archetype:generate -DgroupId=com.cj -DartifactId=webAppDemo -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
从上图可以看出,这个命令运行时间大约2分45秒,忍受不了的同学可以参考这篇文章:maven构建项目慢解决办法
构建成功后的目录结构如下:
修改pom文件如下,并对junit类不添加scope属性,也就是默认为compile
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cj</groupId>
<artifactId>webAppDemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>webAppDemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
<build>
<finalName>webAppDemo</finalName>
</build>
</project>
然后执行 mvn clean package命令,打包项目,新生成的目录结构如下:
使用 jar -xvf 命令解压war包
可以看到,junit类包含在war包内。
如果我们给junit加上scope=test,来看看打包时候会包含在内吗?
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cj</groupId>
<artifactId>webAppDemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>webAppDemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>webAppDemo</finalName>
</build>
</project>
从上图可以看出,junit没有被打包进去 。