Maven的依赖与最佳配置(转载自Maven实战 作者许晓斌)

1、依赖的配置

依赖配置的属性:

<dependencies>
		<dependency>
			<groupId>...</groupId>
			<artifactId>...</artifactId>
			<version>...</version>
			<type>...</type>
			<scope>...</scope>
			<optional>...</optional>
			<exclusions>
                            <exclusion>...</exclusion>
			</exclusions>
		</dependency>

</dependencies>

  • groupId、artifactId和Version:依赖的基本坐标,Maven根据坐标找到相应的依赖。
  • type:依赖的类型,对应于项目坐标定义的packaging。默认为jar
  • scope:依赖的范围
  • optional:标记依赖的可选性
  • exclusions:用来排出传递性的依赖

2、依赖的范围

maven有六种依赖范围compile、test、provided、runtime、system和import(Maven2.0.9及以上)

  • compile:编译依赖范围。默认配置。对于编译、测试和运行的classpath都有效。
  • test:测试依赖范围。对于测试的classpath有效。例如JUnit
  • provided:已提供依赖范围。对于编译、测试有效。运行时无效。如servlet-api,编译测试的时候需要但是运行时在服务器提供,就不需要了。
  • runtime:运行时依赖。对于测试和运行有效。编译无效。
  • system:系统范围依赖。与provide几乎一致。
    <dependency>
             <groupId>javax.sql</groupId>
             <artifactId>jdbc-stdext</artifactId>
             <version>2.0</version>
             <scope>system</scope>
             <systemPath>${java.home}/lib/rt.jar</systemPath>
    </dependency>
  • import:导入依赖范围。不对三种classpath有影响。
3、传递性依赖

一个基于Spring Framework的项目,如果不适用Maven,在项目中就需要手动下载依赖。而Spring Framework又依赖其他的开源类库,所以还要下载别的jar包。Maven的传递依赖机制可以解决这个问题。Maven会解析各个直接依赖的POM,将那些必要的简介依赖以传递依赖的形式引入到当前的项目中。

 compiletestprovided       runtime
compilecompile----runtime
testtest----test
providedprovided--providedprovided
runtimeruntime----runtime

可以看到当第二直接依赖范围是compile时,传递依赖的范围与第一依赖相同;当第二直接依赖范围是test时,依赖不会传递;当第二直接依赖是provided时,只有第一直接依赖是provided时,传递依赖才是provided;当第二直接依赖的范围是runtime时,传递依赖范围与第一依赖相同,出了compile的范围,这时候传递依赖为runtime。

4、依赖的调解

当依赖传递造成问题时,我们需要清楚地知道该传递性依赖的路径。依赖调解的第一原则是:路径最近着优先。例如项目A有这样的依赖关系:A-->B-->C--X(1.0)  A--D--X(2.0),其中X(1.0)的路径长度为3,而X(2.0)的长度为2,因此X(2.0)会被解析使用。

当第一条原则不能解决问题时,使用依赖调解的第二原则:第一声明优先。如A-->B-->Y(1.0)  A-->C--Y(2.0)此时依靠第一原则无法判断,这是后在POM中依赖的声明顺序决定了谁会被解析使用。顺序最靠前的会被解析。

5、可选依赖

有一个项目实现了两个特性,其中一个特性依赖与X,另一个特性依赖与Y,而这两个特性是互斥的,用户不可能同时使用两个特性。那么在依赖属性中添加Optional元素。表名为可选依赖。只会对当前项目有影响,而不会传递。

6、最佳实现

1、排除依赖

  传递性依赖会给项目隐式的引入很多依赖,这简化了项目依赖的管理。有时候也会带来问题。当一个项目有第三方依赖而这个第三方依赖引用了一个类库的SNAPSHOT版本,而这个依赖会传递到项目中。造成项目的不稳定性。或者引用的类库不在Maven的中央类库中。我们想把这种有危害的依赖踢出。可以使用exclusion元素:

<dependency>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <version>...</version>
        <exclusions>
               <exclusion>
                     <groupId>com.test</groupId>
                     <artifactId>project-a</artifactId>
               </exclusion>
        </exclusions>
</dependency>
<dependency>
        <groupId>com.test</groupId>
        <artifactId>project-a</artifactId>
        <version>1.1.0</version>
</dependency>
           
这样我们就可以把project-a不稳定的版本踢出,添加一个新的版本1.1.0.。

2、归类依赖

可以在POM文件中增加属性如:

<properties>
	<spring-version>4.1.3.RELEASE</spring-version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>${spring-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
		<version>${spring-version}</version>
	</dependency>
这样当我们要修改版本的时候,只需要修改property的值就可以了。

3、优化依赖

我们可以通过命令查看当前项目已解析的依赖:

mvn dependency:list
[INFO] ------------------------------------------------------------------------
[INFO] Building Account Email 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ account-email ---
[INFO] 
[INFO] The following files have been resolved:
[INFO]    commons-logging:commons-logging:jar:1.2:compile
[INFO]    junit:junit:jar:4.7:test
[INFO]    org.springframework:spring-beans:jar:4.1.3.RELEASE:compile
[INFO]    org.springframework:spring-expression:jar:4.1.3.RELEASE:compile
[INFO]    javax.activation:activation:jar:1.1:compile
[INFO]    org.springframework:spring-aop:jar:4.1.3.RELEASE:compile
[INFO]    org.springframework:spring-core:jar:4.1.3.RELEASE:compile
[INFO]    aopalliance:aopalliance:jar:1.0:compile
[INFO]    org.springframework:spring-context:jar:4.1.3.RELEASE:compile
[INFO]    com.icegreen:greenmail:jar:1.3.1b:compile
[INFO]    org.springframework:spring-context-support:jar:4.1.3.RELEASE:compile
[INFO]    org.slf4j:slf4j-api:jar:1.3.1:compile
[INFO]    javax.mail:mail:jar:1.4.1:compile
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.686 s
[INFO] Finished at: 2014-12-20T14:13:26+08:00
[INFO] Final Memory: 7M/12M
[INFO] ------------------------------------------------------------------------
我们可以看到所有的依赖及其依赖范围。

同时可以使用命令查看以来的结构:

mvn dependency:tree
得出结果如下:

[INFO] ------------------------------------------------------------------------
[INFO] Building Account Email 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ account-email ---
[INFO] com.juven.mvnbook.account:account-email:jar:1.0.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.1.3.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.2:compile
[INFO] +- org.springframework:spring-beans:jar:4.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.1.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.1.3.RELEASE:compile
[INFO] |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  \- org.springframework:spring-expression:jar:4.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-context-support:jar:4.1.3.RELEASE:compile
[INFO] +- javax.mail:mail:jar:1.4.1:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- junit:junit:jar:4.7:test
[INFO] \- com.icegreen:greenmail:jar:1.3.1b:compile
[INFO]    \- org.slf4j:slf4j-api:jar:1.3.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.656 s
[INFO] Finished at: 2014-12-20T14:15:52+08:00
[INFO] Final Memory: 6M/12M
[INFO] ------------------------------------------------------------------------
同时可以使用另外一个指令来分析依赖的关系及完整性:

mvn dependency:analyze
结果中指出我们需要的依赖及没有使用的依赖:

[INFO] --- maven-dependency-plugin:2.8:analyze (default-cli) @ account-email ---
[WARNING] Used undeclared dependencies found:
[WARNING]    org.springframework:spring-context:jar:4.1.3.RELEASE:compile
[WARNING] Unused declared dependencies found:
[WARNING]    org.springframework:spring-core:jar:4.1.3.RELEASE:compile
[WARNING]    org.springframework:spring-beans:jar:4.1.3.RELEASE:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.701 s
[INFO] Finished at: 2014-12-20T14:18:28+08:00
[INFO] Final Memory: 7M/13M
[INFO] ------------------------------------------------------------------------
而这种依赖的出错时很难查找的,所以先进性依赖的分析是非常有用的。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值