Dependency


https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
https://maven.apache.org/plugins/maven-dependency-plugin/
https://maven.apache.org/enforcer/maven-enforcer-plugin/

1. Important Points#

dependencyManagement:
    管理默认版本,不自动引入 jar

transitive dependency:
    依赖的依赖,会被 Maven 递归解析进项目

dependency mediation:
    多个版本冲突时 Maven 选择最终版本的规则

2. Scope#

Scope Included In Runtime Typical Use
compile yes default
provided no Servlet API, container provides it
runtime yes JDBC driver
test no JUnit, Mockito
import no BOM import only

3. BOM#

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>3.3.1</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
BOM:
    Bill Of Materials
    一组经过配套测试的 dependency versions

4. Version Selection#

Maven mediation:
    nearest definition wins
    same distance uses first declaration
    dependencyManagement can define the version used by transitive dependencies
./mvnw dependency:tree
./mvnw dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind

5. Version Override For Vulnerability#

scenario:
    app-framework -> vulnerable-lib:1.0.0
    vulnerable-lib:1.0.0 has CVE
    app-framework cannot be upgraded today
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>vulnerable-lib</artifactId>
      <version>1.2.3</version>
    </dependency>
  </dependencies>
</dependencyManagement>
workflow:
    find path with dependency:tree
    prefer upgrading direct dependency first
    if blocked, override transitive dependency in dependencyManagement
    run unit tests and integration tests
    verify with dependency scanner
    record why the override exists

6. Exclusions#

<dependency>
  <groupId>org.example</groupId>
  <artifactId>app-framework</artifactId>
  <version>2.0.0</version>
  <exclusions>
    <exclusion>
      <groupId>org.example</groupId>
      <artifactId>bad-lib</artifactId>
    </exclusion>
  </exclusions>
</dependency>
use exclusion when:
    the transitive jar must not be present
    another compatible implementation replaces it
    version override cannot solve the conflict

avoid exclusion when:
    only the version is old
    runtime behavior is unknown

7. Optional Dependency#

<dependency>
  <groupId>org.example</groupId>
  <artifactId>optional-client</artifactId>
  <version>1.0.0</version>
  <optional>true</optional>
</dependency>
optional:
    当前项目可用
    下游项目不会自动继承这个 transitive dependency

8. Enforcer Checks#

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>3.5.0</version>
  <executions>
    <execution>
      <id>enforce</id>
      <goals>
        <goal>enforce</goal>
      </goals>
      <configuration>
        <rules>
          <dependencyConvergence/>
          <requireJavaVersion>
            <version>[21,)</version>
          </requireJavaVersion>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

9. Checklist#

check:
    no dynamic versions
    direct dependencies have clear owners
    BOM imported before manual overrides are reviewed
    vulnerability overrides have comments or PR notes
    dependency:tree output is checked for critical libraries