Mastering SpringBoot Dependency Management with BOM and Version Control

This article explains why SpringBoot projects need centralized dependency management, introduces the concept of a Maven/Gradle BOM, and walks through three practical scenarios—using the parent BOM, manually importing it, and overriding versions—while highlighting common pitfalls and best‑practice solutions.

Java Tech Workshop
Java Tech Workshop
Java Tech Workshop
Mastering SpringBoot Dependency Management with BOM and Version Control

Why Dependency Management Is Needed

SpringBoot projects depend on many libraries (Spring Core, Spring MVC, database drivers, Redis client, third‑party tools, etc.). Without a unified version strategy, three problems arise:

Version conflicts : manually adding Spring Core 5.3.20 while SpringBoot Web Starter 2.7.0 brings Spring 5.3.22, causing class‑loading failures.

Redundant or missing dependencies : transitive relationships (e.g., MyBatis depends on Spring JDBC) can lead to duplicate or omitted artifacts.

High maintenance cost : dozens of dependencies require individual version updates, which is error‑prone.

SpringBoot solves these issues with a BOM (Bill of Materials) that provides unified, compatible versions and simplifies configuration.

What Is a BOM?

A BOM is a special Maven/Gradle POM that defines a set of compatible dependency versions. It acts as a "version dictionary" so developers only need to import the BOM; the actual versions are resolved automatically.

SpringBoot’s BOM

The official SpringBoot BOM is spring-boot-dependencies, which lists compatible versions for the entire SpringBoot ecosystem (Spring, Spring MVC, Redis, MySQL driver, etc.). When a SpringBoot project uses the default parent POM, this BOM is already imported, which is why starter dependencies do not require explicit version numbers.

Core Usage Scenarios (Covering 99% of Needs)

Scenario 1: Use the SpringBoot Parent BOM

Creating a SpringBoot project automatically adds the parent spring-boot-starter-parent, which imports spring-boot-dependencies. You can then add starter dependencies without specifying versions.

<!-- Parent project that includes the SpringBoot BOM -->
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.7.0</version>
  <relativePath/>
</parent>

<!-- Add dependencies; versions are supplied by the BOM -->
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
  </dependency>
</dependencies>

Advantage: no manual version management; SpringBoot guarantees compatibility.

Scenario 2: Manually Import the BOM When the Parent Cannot Be Inherited

If a module cannot inherit spring-boot-starter-parent, import the BOM via the dependencyManagement section.

<!-- Manually import SpringBoot BOM for version control -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.7.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<!-- Add dependencies without versions – they inherit from the BOM -->
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
</dependencies>

Note: dependencyManagement only defines versions; you still need to list the actual dependencies under dependencies.

Scenario 3: Override BOM Versions

When a specific version is required (e.g., MySQL 8.0 while the BOM defaults to 5.7), you can override either locally in a dependency or globally via properties.

Method 1 – Local Override in a Dependency

<dependencies>
  <!-- Override MySQL driver version defined in the BOM -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
  </dependency>
</dependencies>

Method 2 – Global Override via Properties

<properties>
  <!-- Global override for MySQL driver version -->
  <mysql.version>8.0.32</mysql.version>
  <!-- Global override for Redis version -->
  <redis.version>3.2.10</redis.version>
</properties>

<dependencies>
  <!-- No version needed; the property value is used automatically -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
  </dependency>
</dependencies>

Using properties lets you change a version in one place, avoiding scattered overrides.

Key Features of SpringBoot BOM

Version unification : defines a compatible set of versions, preventing conflicts.

Simplified configuration : no need to specify versions for each dependency.

Overridable : you can manually set a version to replace the BOM default.

Transitivity : imported BOM versions apply to transitive dependencies (e.g., Spring Core version is controlled when you add spring-boot-starter-web).

Common Dependency‑Version Issues and Solutions

Dependency Conflicts

Symptoms: ClassNotFoundException, NoSuchMethodError, duplicate JARs.

Solution: Prefer the SpringBoot BOM; use Maven’s dependency tree view to locate conflicts and exclude unwanted artifacts:

<!-- Exclude a conflicting transitive dependency -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Incompatible Manual Versions

Wrong: arbitrarily mixing SpringBoot 2.7.0 with Spring 6.0.

Correct: if you must customize a version, ensure it matches the SpringBoot compatibility matrix (refer to the official docs).

Redundant Dependencies

Wrong: adding the same library multiple times or pulling in unnecessary artifacts.

Correct: rely on starter dependencies, which automatically bring in the required transitive libraries.

Summary

For typical projects, inherit the SpringBoot parent POM and let the BOM manage versions automatically.

If you cannot inherit the parent, import spring-boot-dependencies via dependencyManagement to gain the same version control.

When custom versions are needed, prefer global overrides through properties to keep the build clean and maintainable.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

dependency-managementmavenspring-bootversion-controlbom
Java Tech Workshop
Written by

Java Tech Workshop

Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.