Maven(一)坐标和依赖
-
坐标
在实际生活中,地址可以看成是一种坐标。省、市、区、街道等一系例信息可以唯一标识城市中的居住地和工作地址。而为标识开发过程中数量巨大的构件,基于预定义的规则,Maven定义了一规则:世界上的任何一个构件都可以使用Maven坐标唯一标识,Maven坐标的元素包括groupId、artifactId、version、packaging、classifier。只需提供正确的坐标元素,Maven就能找到对应的构件。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
上面的xml定义即可以将spring的core包依赖加到本地的classpath中。
1. ##### groupId
定义当前maven项目隶属的实际项目。Maven项目和实际项目并不是一对一的关系。例如实际项目SpringFramework,对应很多的maven项目/模块,如spring-core、spring-context.一个实际项目往往划分成很多模块。其次,groupId不应该对应项目隶属的组织或者公司,因为一个组织下会有很多实际项目,如果groupId只定义到组织级别,后面会看到,artifactId只能定义为Maven项目,实际的项目这一层将难以定义。groupId的表示方式与java包名的表示方式类似,通常与域名反向一一对应。
2. ##### artifactId
定义实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀,如spring下的spring-core,方便寻找。默认情况下,生成构件,文件名以artifactId作为开头,如spring-security-core-4.1.0.RELEASE.jar,这样方便区分和定位构件位置。
3. ##### version
定义Maven项目所处的版本,如上spring-security-core-4.1.0.RELEASE的版本是4.1.0.RELEASE,一般还有SNAPHOT版,后续会介绍。
4. ##### packaging
定义Maven项目的打包方式,通常与生成构件的文件后缀名一致,例如war,jar。以及maven父项目的pom方式。默认是jar。打包的方式会影响Maven构建的生命周期。
5. ##### classifiler
帮件定义构件输出的附属构件。附属构件与主构件对应,如主构件spring-security-core-4.1.0.RELEASE.jar,还会有通过插件获取的附属构件(源码包) spring-core-4.3.7.RELEASE-sources.jar,这里sources即是classifiler。需要注意的是,附属构件不是项目直接默认生成的,而是附加的插件来生成。
***上述5种元素,只有groupId、artifactId、version是必须提供的、packagin是可选的,默认为jar, classifiler是不能直接定义的。***
-
依赖配置
一个依赖的声明可以包含下面的元素:
<project>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<type></type>
<scope></scope>
<optional></optional>
<exclusions>
<exclusion></exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
dependencies下面可以包含一个或多个dependency元素,用以声明一个或多个依赖。依赖包含的元素有:
1. groupId、artifactId、version:依赖的基本坐标,必须提供这三项Maven才能找到需要的依赖。
2. type: 依赖的类型,对应项目坐标定义的packaging。大部分情况下不必声明,默认为jar。
3. scope: 依赖的范围,下面会详细介绍。
4. optional: 标记依赖是否可选。
5. exclusions: 用来排除传递性依赖。
-
依赖范围
Maven在编译项目主代码的时候会使用一套classpath,例如,我们主代码用到了spring-core,该文件以依赖的方式引入了classpath中。然后我们又用到了JUnit用于测试,Maven在测试时会使用另一套classpath,JUnit的依赖范围是test。最后,实际运行Maven项目的时候,又会使用一套classpath,spring-core需要在该classpath中,而JUnit则不需要。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。
Maven有以下的几种依赖范围:- compile: 编译的依赖范围。没有指定scope时的默认值,此依赖范围的Maven的依赖,对于编译、测试、运行三种classpath都有效。
- test: 测试依琐范围。只对测试classpath有效,编译主代码和运行项目的时候无法使用此依赖。
- provided: 已提供的依赖范围。对于编译和测试classpath有效,但在运行时无效。如servlet-api,编译和测试项目的时候都需要该依赖,但在运行的时候,由于容器已经提供,不需要重复引入。
- runtime: 运行时依赖范围。对于测试和运行classpath有效,但在编译时无效,像是JDBC的驱动实现包。主代码编译只需要JDK提供的JDBC接口,只有在运行或者测试才需要上述接口的实现。
- system: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,system范围的依赖必须通过systemPath元素显示指定依赖文件的路径。此类依赖不是通过Maven仓库解析的,往往与本机系统绑定,会造成构建的不可移植,谨慎使用。
<dependecy>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
<dependecy>
6. import: 导入依赖范围。Maven 2.0.9开始支持,该依赖范围不会对三种classpath产生实际影响,后续介绍dependencyManagement时详细介绍。
浙公网安备 33010602011771号