1. 什么是依赖管理?
项目中会依赖第三方jar包,解决依赖这些jar包出现的冲突、更新升级等问题。
2. maven 如何依赖?
通过配置maven项目的pom.xml文件进行依赖。如junit依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</test>
</dependency>
<dependencies>
dependencies 标签声明依赖,每一个dependency 子标签是声明一个依赖,depandency是声明一个maven坐标,通过坐标从maven中央仓库下载相应依赖jar到本地仓库进行使用。
3. 依赖 scope
依赖标签dependency中有个 scope标签 确定此依赖的classpath 可用范围。
例如:
1. 对于junit 主源码不可用,测试源码可用,不被打包
2. 开发j2ee时会使用servlet-api ,主源码和测试源码都需要使用,但是web容器会提供servlet-api,所以在发布打包是不需要打包此依赖,所有依赖scope 设置为 provided
4. 依赖归类
项目的开发会使其依赖会逐渐增多,比如项目依赖spring的一些jar,它们的groupId相同,artifactId不同。为了管理其版本对其统一升级,逐个修改其版本是件很繁琐的事,当pom.xml很大的时候说不定会犯错,还会出现一些版本不兼容的问题。maven提出了它的解决方案:
<dependencies>
<dependency>
<groupId>org.spring.framework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.spring.framework</groupId>
<artifactId>spring-mock</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<properties>
<spring.version>2.5</spring.version>
</properties>
这里我们定义了一个名称为spring.version 的maven属性,通过${spring.version}引用该属性,所有spring相关依赖的version都为${spring.version},当maven运行的时候会用spring.version值来填充对于应用。当spring升级是只需修改spring.version的值即可保证spring的依赖都是同一版本。
5. 分类器
举个简单的例子,当我们需要依赖TestNG的时候,简单的声明GAV会出错,因为TestNG强制需要你提供分类器,以区别jdk14和jdk15,我们需要这样声明对TestNG的依赖:
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.7</version>
<classifier>jdk15</classifier>
</dependency>
你会注意到maven下载了一个名为testng-5.7-jdk15.jar的文件。其命名模式实际上是<artifactId>-<version>-<classifier>.<packaging>。理解了这个模式以后,你就会发现很多文件其实都是默认构件的分类器扩展,如 myapp-1.0-test.jar, myapp-1.0-sources.jar。
分类器还有一个非常有用的用途是:我们可以用它来声明对test构件的依赖,比如,我们在一个核心模块的src/test/java中声明了一些基础 类,然后我们发现这些测试基础类对于很多其它模块的测试类都有用。没有分类器,我们是没有办法去依赖src/test/java中的内容的,因为这些内容 不会被打包到主构件中,它们单独的被打包成一个模式为--test.jar的文件。
我们可以使用分类器来依赖这样的test构件:
<dependency>
<groupId>org.myorg.myapp</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
<classifier>test</classifier>
</dependency>
6.依赖管理
实际的项目中,你会有一大把的Maven模块,而且你往往发现这些模块有很多依赖是完全项目的,A模块有个对spring的依赖,B模块也有,它们的依赖配置一模一样,同样的groupId, artifactId, version,或者还有exclusions, classifer。细心的分会发现这是一种重复,重复就意味着潜在的问题,Maven提供的dependencyManagement就是用来消除这种 重复的。
正确的做法是:
1. 在父模块中使用dependencyManagement配置依赖
2. 在子模块中使用dependencies添加依赖
dependencyManagement实际上不会真正引入任何依赖,dependencies才会。但是,当父模块中配置了某个依赖之后,子模块只需使用简单groupId和artifactId就能自动继承相应的父模块依赖配置。
例:
父模块中声明:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>a-parent</artifactId>
<version>1.0.0</version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
...
<dependencies>
</dependencyManagement>
子模块中声明:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>a-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>project-a</artifactId>
...
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
项目中会依赖第三方jar包,解决依赖这些jar包出现的冲突、更新升级等问题。
2. maven 如何依赖?
通过配置maven项目的pom.xml文件进行依赖。如junit依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</test>
</dependency>
<dependencies>
dependencies 标签声明依赖,每一个dependency 子标签是声明一个依赖,depandency是声明一个maven坐标,通过坐标从maven中央仓库下载相应依赖jar到本地仓库进行使用。
3. 依赖 scope
依赖标签dependency中有个 scope标签 确定此依赖的classpath 可用范围。
依赖范围及作用如下:
- system: 和provided类似,但要求jar是你的系统里已有的,不会在repository里找,如rt.jar,tools.jar这些。
- import: 简单的说,你的项目的pom可以继承另一个项目的pom,从而继承了父项目的依赖关系,但是因为之后single inheritance的限制,所以创造了import,使得你可以“导入”或者说“继承”任何一到多个项目的依赖关系。例如:
1. 对于junit 主源码不可用,测试源码可用,不被打包
2. 开发j2ee时会使用servlet-api ,主源码和测试源码都需要使用,但是web容器会提供servlet-api,所以在发布打包是不需要打包此依赖,所有依赖scope 设置为 provided
4. 依赖归类
项目的开发会使其依赖会逐渐增多,比如项目依赖spring的一些jar,它们的groupId相同,artifactId不同。为了管理其版本对其统一升级,逐个修改其版本是件很繁琐的事,当pom.xml很大的时候说不定会犯错,还会出现一些版本不兼容的问题。maven提出了它的解决方案:
<dependencies>
<dependency>
<groupId>org.spring.framework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.spring.framework</groupId>
<artifactId>spring-mock</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<properties>
<spring.version>2.5</spring.version>
</properties>
这里我们定义了一个名称为spring.version 的maven属性,通过${spring.version}引用该属性,所有spring相关依赖的version都为${spring.version},当maven运行的时候会用spring.version值来填充对于应用。当spring升级是只需修改spring.version的值即可保证spring的依赖都是同一版本。
5. 分类器
举个简单的例子,当我们需要依赖TestNG的时候,简单的声明GAV会出错,因为TestNG强制需要你提供分类器,以区别jdk14和jdk15,我们需要这样声明对TestNG的依赖:
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.7</version>
<classifier>jdk15</classifier>
</dependency>
你会注意到maven下载了一个名为testng-5.7-jdk15.jar的文件。其命名模式实际上是<artifactId>-<version>-<classifier>.<packaging>。理解了这个模式以后,你就会发现很多文件其实都是默认构件的分类器扩展,如 myapp-1.0-test.jar, myapp-1.0-sources.jar。
分类器还有一个非常有用的用途是:我们可以用它来声明对test构件的依赖,比如,我们在一个核心模块的src/test/java中声明了一些基础 类,然后我们发现这些测试基础类对于很多其它模块的测试类都有用。没有分类器,我们是没有办法去依赖src/test/java中的内容的,因为这些内容 不会被打包到主构件中,它们单独的被打包成一个模式为--test.jar的文件。
我们可以使用分类器来依赖这样的test构件:
<dependency>
<groupId>org.myorg.myapp</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
<classifier>test</classifier>
</dependency>
6.依赖管理
实际的项目中,你会有一大把的Maven模块,而且你往往发现这些模块有很多依赖是完全项目的,A模块有个对spring的依赖,B模块也有,它们的依赖配置一模一样,同样的groupId, artifactId, version,或者还有exclusions, classifer。细心的分会发现这是一种重复,重复就意味着潜在的问题,Maven提供的dependencyManagement就是用来消除这种 重复的。
正确的做法是:
1. 在父模块中使用dependencyManagement配置依赖
2. 在子模块中使用dependencies添加依赖
dependencyManagement实际上不会真正引入任何依赖,dependencies才会。但是,当父模块中配置了某个依赖之后,子模块只需使用简单groupId和artifactId就能自动继承相应的父模块依赖配置。
例:
父模块中声明:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>a-parent</artifactId>
<version>1.0.0</version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
...
<dependencies>
</dependencyManagement>
子模块中声明:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>a-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>project-a</artifactId>
...
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>