Maven依赖处理

Maven Dependency Scopes

  • 参考文章:https://www.baeldung.com/maven-dependency-scopes,https://blog.csdn.net/kimylrong/article/details/50353161

Maven有6个依赖域。他们分别是Compile,Provided,Runtime,Test,System,Import。这里需要解释一下scope的依赖传递A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
当C是test或者provided时,C直接被丢弃,A不依赖C;
否则A依赖C,C的scope继承于B的scope。

  • Compile

默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。具有传递依赖性,也就是父依赖的scope为compile,本项目中构建的所有流程中都会包括该依赖。

  • Provided

provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。一个典型的例子,web服务器一般在运行时提供了Servlet API。不具有传递依赖性,也就是父依赖的scope为provided,本项目中直接丢掉该依赖。


    javax.servlet
    servlet-api
    2.5
    provided

  • Runtime

runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API jar是compile的,具体实现是runtime的,compile只需要知道接口就足够了。oracle jdbc驱动jar包就是一个很好的例子。另外runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。

# JDBC Driver就是一个很好的例子

    mysql
    mysql-connector-java
    6.0.6
    runtime

  • Test

scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。

# JUnit就是一个很好的例子

    junit
    junit
    4.12
    test

  • System

从参与度来说,与provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。

之前有做个一个图片视频的采集服务,项目是用maven管理的,并用docker部署。需要用到一个外部第三方包。所以我们需要把该本地包使用maven管理起来


            thermogroup
            infrared
            1.0
            system
            ${project.basedir}/lib/thermogroupsdk4java.jar
        

但是这里有一个问题,因为scope是system,所以使用maven打包的时候是不会把该本地jar包打包进去的。所以在打包docker的时候需要在dockerfile文件中显式的加进去。当时不想这么操作,通过配置maven插件的includeSystemScope参数为true,把本地包也打包进去。


                org.springframework.boot
                spring-boot-maven-plugin
                
                    true
                
            
  • Import

scope为import标识这个依赖会被pom文件中的所有声明的依赖替代。Import只能结合dependencyManagement使用,用来做包管理和版本控制。最常见的案例是我们使用springboot,spring cloud的时候,我们使用dependencyManagement做一个大版本管理,后续子项目可以直接通过dependency声明使用的依赖而不需要指定版本(继承dependencyManagement pom文件中声明的依赖版本)。


        
            
            
                org.springframework.boot
                spring-boot-dependencies
                2.1.10.RELEASE
                pom
                import
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.RELEASE
                pom
                import
            
            
                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                2.1.0.RELEASE
                pom
                import
            
        
    

Maven的Dependency机制

参考文档:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

Maven依赖的管理是maven的核心功能,管理单个项目模块通常是简单的,但是对于复杂的项目通常涉及到上百个模块,maven的依赖管理就显得尤其重要。

Transitive Dependencies-依赖的传递性

由于依赖具有传递性,对于一个大一点的项目依赖的拓扑图就会变得越来越大,maven提供了以下几种方式来限制最终选择哪个依赖。

  • Dependency mediation-依赖调节
    当一个项目通过传递性依赖同一个库的不同版本时,会遵循就近原则。比如下面的这个依赖拓扑图,由于D2.0版本的库路径长度(A->B->C->D2.0)大于(A->E->D1.0)的路径长度,所以maven最终会依赖D1.0版本的库。
 A
  ├── B
  │   └── C
  │       └── D 2.0
  └── E
      └── D 1.0

如果你需要显式的依赖D2.0,最佳实践是在自己的项目重声明依赖D2.0,这种它的路径就是(A->D2.0),会优先选择。通常我们最好显式的声明自己项目中使用的依赖,不要依靠依赖的传递性。

A
  ├── B
  │   └── C
  │       └── D 2.0
  ├── E
  │   └── D 1.0
  │
  └── D 2.0    
  • Dependency management
    参考上述对scope import的解读
  • Dependency scope
    参考上述对scope传递性的解读
  • Excluded dependencies
    显示的排除依赖

      group-a
      artifact-a
      1.0
      
        
          group-c
          excluded-artifact
        
      
    
  • Optional dependencies
    可选依赖

    
      sample.ProjectA
      Project-A
      1.0
      compile
      true 
    

Maven的Profile的使用

在pom文件中声明profiles,可以设置默认profile.启动的时候以启动的分支为准。


        
            local
            
                local
            
            
                true
            
        
        
            test
            
                test
            
        
        
            prod
            
                prod
            
        
    

我们可以在pom文件中通过${env}环境变量可以获取具体哪个分支,比如下面我想让不同的分支打包到harbor不同的镜像仓库,可以使用该环境变量。

 
        
        
        dev2.out:8082
        
        leather.${env}
    

你可能感兴趣的:(Maven依赖处理)