Maven Dependency Mechanism

Maven Dependency Mechanism is one of the core features of the Apache Maven build tool. It can automatically download and manage the external libraries (JAR files) required by the project and their dependencies.

The Maven dependency mechanism greatly simplifies the build process of Java projects, allowing developers to avoid manually downloading and managing various third-party libraries.

Maven stores millions of open source libraries through the Maven Central Repository. When you declare a dependency in your project, Maven automatically downloads that library and all its dependencies from the repository.

Dependency Declaration

Declare it in pom.xml using the <dependency> tag:

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

Basic Concepts of Maven Dependencies

1. Coordinate System (Coordinates)

Maven uses three basic coordinates to uniquely identify a dependency:

  • groupId: Defines the organization or company to which the project belongs (e.g.,org.apache)
  • artifactId: Defines the name of the project (e.g.,commons-lang3)
  • version: Defines the version of the project (e.g.,3.12.0)

Together these three elements form the unique identifier of a Maven dependency.

2. Dependency Scope

Maven defines different dependency scopes, which determine in which phases a dependency is available:

  • compile(default): Available at compile, test, and runtime
  • provided: Available at compile and test time, but provided by the JDK or container at runtime
  • runtime: Only needed at test and runtime
  • test: Only needed during test compilation and execution
  • system: Similar to provided, but requires an explicit JAR path

3. Transitive Dependencies

When project A depends on project B, and project B depends on project C, Maven automatically introduces project C as a dependency of project A. This automatic dependency handling feature is called transitive dependencies.

The transitivity rules depend on Scope:

Current Dependency Scope \ Transitive Dependency Scopecompileprovidedruntimetest
compilecompile-runtime-
providedprovidedprovidedprovided-
runtimeruntime-runtime-
test----

How to Use Maven Dependencies in Projects

1. Adding Dependencies in pom.xml

In the Maven project'spom.xmlfile,<dependencies>section is used to declare project dependencies:

Example

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>

2. Dependency Exclusions

Sometimes you may need to exclude a transitive dependency; you can use<exclusions>tag:

Example

<dependency>
    <groupId>com.example</groupId>
    <artifactId>example-library</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.unwanted</groupId>
            <artifactId>unwanted-dependency</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3. Dependency Management

In multi-module projects, you can use in the parent POM<dependencyManagement>to uniformly manage dependency versions:

Example

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.20</version>
        </dependency>
    </dependencies>
</dependencyManagement>

When child modules reference dependencies, they only need to declare groupId and artifactId, without specifying the version.


Advanced Features of Dependency Management

Dependency Version Management

UsedependencyManagementto uniformly manage versions:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.18</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 子模块使用时无需指定版本 -->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
</dependencies>

BOM Import

Manage versions of a set of related dependencies:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.6.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Optional Dependencies

Mark dependencies as optional and not transitive:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>optional-lib</artifactId>
    <version>1.0</version>
    <optional>true</optional>
</dependency>

Maven Dependency Resolution Mechanism

1. Dependency Mediation

When version conflicts occur, Maven resolves them using the following rules:

  1. Nearest definition wins (the version with the shortest path in the dependency tree is selected)
  2. If the path length is the same, the dependency declared first takes precedence.

2. Impact of Dependency Scope

Dependencies with different scopes affect transitivity:

  • compile scope dependencies are transitive
  • provided and test scope dependencies are not transitive
  • runtime scope dependencies are transitive with runtime scope

Final packaging results of dependencies with different scopes:

ScopeWhether packagedTypical use
compileYesCore dependencies
providednoProvided by container
runtimeYesNeeded at runtime
testnoUnit tests

3. Optional Dependencies

Dependencies marked as optional are not transitive:

Example

<dependency>
    <groupId>com.example</groupId>
    <artifactId>optional-lib</artifactId>
    <version>1.0</version>
    <optional>true</optional>
</dependency>

Commands Related to Dependencies

View dependency tree:

mvn dependency:tree

Analyze dependency issues:

mvn dependency:analyze

Download dependencies to directory:

mvn dependency:copy-dependencies

Maven Repository

1. Repository Types

  • Local repository: Located in the user's home directory under.m2/repositorydirectory
  • Central repository: Maven's default public repository
  • Remote repository: A private repository built by a company or organization

2. Repository Configuration

You can configure inpom.xmlorsettings.xmlconfigure the repository:

Example

<repositories>
    <repository>
        <id>my-repo</id>
        <url>http://repo.example.com/maven2</url>
    </repository>
</repositories>

Best Practices

  1. Explicitly specify dependency versions: Avoid using dynamic versions such as LATEST or RELEASE
  2. Regularly update dependencies: Usemvn versions:display-dependency-updatesto check available updates
  3. Use BOM: For large frameworks (e.g., Spring), use a Bill of Materials to uniformly manage versions
  4. Clean up unused dependencies: Regularly runmvn dependency:analyzeto check for unused dependencies
Other extensions