Если зависимость в dependencyManagement, но не в dependencies, будет ли она подключена в приложение
Что проверяют
Понимаете ли вы разницу между объявлением версии и подключением зависимости. Следом почти всегда идёт вопрос про транзитивные зависимости и про то, как работает BOM, например spring-boot-dependencies.
Как отвечать
Нет, не будет. dependencyManagement ничего не добавляет в classpath, это таблица правил: какие version, scope и exclusions применить, если артефакт где-то встретится. Подключает зависимость только секция <dependencies>, и там её можно объявить без <version>: версия подтянется из управления.
Нюансы, ради которых вопрос задают:
- транзитивные зависимости: если артефакт уже приходит через другую библиотеку, управляемая версия применится и к нему.
dependencyManagementне подключает, но меняет версию того, что подключено и так. Этим закрывают уязвимую версию транзитивной библиотеки; - наследование: управление из родительского
pom.xmlдействует на все дочерние модули. А вот<dependencies>родителя наследуются целиком, и это частая причина лишних библиотек в модулях; - BOM: артефакт с
<type>pom</type>и<scope>import</scope>внутриdependencyManagementимпортирует чужую таблицу версий. Так подключаютspring-boot-dependencies, BOM от Jackson, JUnit, Testcontainers; - Spring Boot: стартеры пишутся без версий именно потому, что
spring-boot-starter-parentсодержит такойdependencyManagement.
Проверяют это двумя командами: mvn dependency:tree показывает, что реально попало в сборку, а mvn help:effective-pom выводит итоговую модель с подставленными версиями. В дереве подменённая версия помечается как version managed from.
Где спотыкаются
Говорят, что зависимость из dependencyManagement родителя «сама появится» в дочерних модулях. Не появится, пока модуль не объявит её в <dependencies>.
Считают, что dependencyManagement на сборку не влияет вовсе. Он переопределяет версии транзитивных зависимостей, и после его правки поведение приложения может измениться без единой новой строки в <dependencies>.
Кладут BOM с <scope>import</scope> в обычные <dependencies>. Импорт работает только внутри dependencyManagement, в другом месте он бесполезен.