依赖

    对Maven有过了解的会知道Maven通过Pom文件管理项目中用到的jar包,如果我们需要使用一个jar包,则需要在pom文件中添加一个依赖,通过坐标标识我们想要找到的具体jar包。通过三个坐标可以定位一个jar包,maven中有生命周期,在不同时期使用的jar包可以使用依赖范围标识。 

    在pom文件的dependencied标签下的dependency即依赖,例如我们添加两个依赖:

<dependencies>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
     <version>5.0.0.RC3</version>
  </dependency>

  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
</dependencies>

依赖范围scope

    scope即依赖范围,共有5种,compile、test、runtime、provided、system。

    我们以打入war包为例。

     compile:编译依赖范围,在编译、测试、运行时都需要,会在上述三种情况下将该jar打入war包,

     test:测试依赖范围,测试时需要,编译、运行时不需要,则在编译和运行时不会将此jar包打入war包,

     runtime:运行时依赖范围,测试和运行时都需要,编译不需要,则在编译是不会打入war包,

     provided:已提供依赖范围,编译和测试时需要。运行时不需要,则运行时不会将此打入war包,

     system:系统依赖范围,本地依赖。

传递依赖

    依赖是会被传递的,如A-->C B-->A==>B-->C。

    在添加依赖时如果不指定依赖范围,默认的是compile依赖范围,假如现在C依赖了上述第一部分举例中的spring的依赖,而且这个依赖是默认的compile范围,则在编译、运行时、测试时都会将该jar包打到A的war包中,B调用A同理。

    如果我们不想要传递依赖,则需要看下一部分的传递依赖的解决进行解决,有时候我们可以使用传递依赖,像测试使用的junit包,每一层都会使用,我们就可以指定一个统一的版本写在根目录下的pom文件中,然后传递依赖到各个层。

传递依赖带来的问题

     拿A-->C举例

    1.当A调用C时,如果C中的包没有指定依赖范围,即可传递的,当C中jar包数量很多时,这所有的jar包都会打到A对应的war包下,影响性能。

    2.当A中依赖了版本为5.0.0 RC2版本的spring context时,C中依赖了版本为5.0.0.RC3的spring context,而A调用C,则会将C中依赖的spring context依赖到A中,这时候由于版本不同,则会引起版本冲突。

解决传递依赖

     1.在自己服务内部

      假如在自己的服务中分为三层,web,api,service,web-->api,service-->api,如果在api中的某一个依赖我们不想让他传递依赖,则需要在该依赖上加scope标签,并指定依赖范围为provided,这样api中设置为provided的依赖就不会传递到调用api的web和service层,就不会导致包冲突等问题。如api中的spring依赖设置为provided:

 

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.0.RC2</version>
    <scope>provided</scope>
</dependency>

 

   2.自己服务调用公共封装服务

 

    假如一个项目组一共有9个服务,而这9个服务都会调用一个封装的公共base库,如A-->base,而在base中有一个spring的依赖,并且这个spring依赖没有设置为provided,而在A中我们不想用,我们有两种解决方案:①修改base中的spring依赖范围为provided,这时候问题来了,如果我们没有权限修改,那就不能修改了,如果我们要修改,修改完后会对其他8个服务造成不可预估的影响,这时候也是不应该修改的。修改公共base行不通,就只能从自己服务出发,我们可以在调用base时将不需要的jar包排除,如:

 

<dependency>
       <groupId>base</groupId>
       <artifactId>demo-base</artifactId>
   <exclusions>
     </exclusion>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
     </exclusion>
   </exclusions>
  </dependency>

 

总结

 

    传递依赖是很常见的现象,如何避免传递依赖以及如何解决传递依赖需要我们在实践过程中通过问题来提升,在实践过程中有了新问题会及时记录,分享给广大maven爱好者。