← Назад к вопросам

В чем разница между dependencyManagement и dependencies?

2.0 Middle🔥 131 комментариев
#Другое#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# dependencyManagement vs dependencies в Maven

Это ключевая разница в POM файле, которая влияет на версионирование зависимостей в многомодульных проектах.

Основная разница

dependencies: добавляет зависимость в проект

dependencies — это раздел, где вы ДОБАВЛЯЕТЕ библиотеки, которые нужны вашему проекту.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.0.0</version>
    </dependency>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Когда вы добавляете зависимость в раздел dependencies:

  • Артефакт загружается и используется в проекте
  • Все транзитивные зависимости также загружаются
  • Можно опустить version, если указана версия в dependencyManagement

dependencyManagement: управляет версиями

dependencyManagement — это раздел для определения версий зависимостей, но БЕЗ их автоматического добавления.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.0.0</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Когда вы добавляете зависимость в раздел dependencyManagement:

  • Зависимость НЕ загружается автоматически
  • Определяется рекомендуемая версия для других модулей
  • Дочерние модули могут использовать эту версию БЕЗ указания версии в своих dependencies

Практический пример: многомодульный проект

Структура проекта

my-project/
├── pom.xml (Parent POM)
├── module-api/
│   └── pom.xml
├── module-core/
│   └── pom.xml
└── module-web/
    └── pom.xml

Parent POM (my-project/pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <!-- dependencyManagement: определяем версии для детей -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot BOM (Bill of Materials) -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>3.0.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <!-- Наши собственные версии -->
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>my-api</artifactId>
                <version>1.0.0</version>
            </dependency>
            
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <!-- Сами в parent'е можем указать общие зависимости -->
    <dependencies>
        <!-- Общие для всех тесты -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Child POM (module-api/pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>module-api</artifactId>
    <version>1.0.0</version>
    
    <!-- dependencies: добавляем нужные библиотеки -->
    <dependencies>
        <!-- версия будет взята из parent'а dependencyManagement -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- версия НЕ указана, будет использована из parent -->
        </dependency>
        
        <!-- junit будет унаследован из parent dependencies -->
    </dependencies>
</project>

Child POM (module-web/pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>module-web</artifactId>
    <version>1.0.0</version>
    
    <dependencies>
        <!-- Используем свою зависимость (версия из parent) -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>module-api</artifactId>
        </dependency>
        
        <!-- Spring Web (версия из parent) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

Преимущества dependencyManagement

1. Централизованное управление версиями

<!-- Parent POM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.0.0</version>  <!-- Одно место для изменения! -->
        </dependency>
    </dependencies>
</dependencyManagement>

Если нужно обновить Spring Boot с 3.0.0 на 3.1.0, меняете ТОЛЬКО одно место в parent'е.

2. Избежание конфликтов версий

<!-- Проблема БЕЗ dependencyManagement -->
<!-- module-api/pom.xml -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>  <!-- версия 3.11 -->
</dependency>

<!-- module-web/pom.xml -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12</version>  <!-- версия 3.12 -->
</dependency>

-- Конфликт! Какую версию использовать?

-- Решение С dependencyManagement --
<!-- Parent POM -->
<dependencyManagement>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12</version>  <!-- одна версия для всех -->
    </dependency>
</dependencyManagement>

<!-- module-api/pom.xml и module-web/pom.xml -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <!-- версия будет 3.12 из parent -->
</dependency>

3. Отсутствие дублирования версий

<!-- БЕЗ dependencyManagement: повторение в каждом модуле -->
<!-- module-1/pom.xml -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

<!-- module-2/pom.xml -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

<!-- C dependencyManagement: только в parent'е -->
<!-- Parent POM -->
<dependencyManagement>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>31.1-jre</version>
    </dependency>
</dependencyManagement>

Import BOM (Bill of Materials)

Можно импортировать готовые BOM'ы (например, Spring Boot):

<dependencyManagement>
    <dependencies>
        <!-- Импортируем весь Spring Boot BOM -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Теперь все зависимости Spring Boot будут иметь правильные версии:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- версия из импортированного BOM -->
    </dependency>
</dependencies>

Наглядное сравнение

Сценарий 1: dependencyManagement (правильный подход)

Parent POM:
  dependencyManagement:
    - junit 4.13.2
    - spring-boot 3.0.0

Module A (наследует parent):
  dependencies:
    - junit        ← версия из parent (4.13.2)
    - spring-boot  ← версия из parent (3.0.0)

Module B (наследует parent):
  dependencies:
    - junit        ← версия из parent (4.13.2)
    - spring-boot  ← версия из parent (3.0.0)

Все модули используют одинаковые версии!

Сценарий 2: dependencies без dependencyManagement (конфликты)

Module A:
  dependencies:
    - junit 4.13.2  ← версия 4.13.2

Module B:
  dependencies:
    - junit 4.12    ← версия 4.12 (конфликт!)
    - spring-boot 3.0.0  ← версия 3.0.0

Module C:
  dependencies:
    - spring-boot 2.7.0  ← версия 2.7.0 (конфликт!)

Конфликты версий в проекте!

Практический пример Maven проекта

// Parent pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>my-parent</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring-boot.version>3.0.0</spring-boot.version>
        <junit.version>4.13.2</junit.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>
            
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <modules>
        <module>module-api</module>
        <module>module-web</module>
    </modules>
</project>

Когда использовать

dependencyManagement используй когда:

  • Многомодульный проект — нужно согласовать версии
  • Нужна гибкость — дочерние модули могут выбрать использовать зависимость или нет
  • Предотвращение конфликтов — одна версия для всех модулей
  • Экспорт API — определение версий для потребителей твоей библиотеки

dependencies используй для:

  • Добавления библиотек — которые действительно нужны проекту
  • Одномодульных проектов — можно указать версию прямо
  • Специфичные зависимости — которые нужны только этому модулю

Итог

АспектdependencyManagementdependencies
ЦельОпределить версииДобавить зависимости
ЗагружаетНетДа
ИспользованиеParent/BOMChild модули
Версия обязательнаДаНет (если в dependencyManagement)
ОбластьВерсионированиеФункционал

dependencyManagement — это инструмент для управления и согласования версий в многомодульных проектах, а dependencies — это список библиотек, которые действительно используются в проекте.