Логотип Workflow

Article

Updated at:

Stage 3: Dependency Management

Этап 3 - Dependency Management: управление зависимостями

Backend почти никогда не использует только JDK classes. Он использует Spring, database driver, JSON библиотека, тест framework, logging, validation и множество маленьких библиотеки, которые приходят косвенно.

Зависимость - это внешний артефакт, который проекту нужен для compile, run или тест. Инструменты сборки идентифицируют его по координатам: groupId, артефактId и версия.

Этап 3 - Dependency Management: управление зависимостями

Какую проблему это решает

Coordinates должны быть точными, потому что разные организации публикуют артефакты с похожими именами. groupId определяет группу или компанию, артефактId - библиотеку, версия - конкретный релиз.

Scope контролирует, где зависимость видна. compile или Gradle implementation используется production code. provided доступна при compilation, но поставляется запуск приложения environment. запуск приложения нужна только при запуске. тест доступна только тесты. system указывает на локальный file и почти никогда не должен использоваться.

Transitive зависимости - это зависимости твоих зависимости. Если добавить Spring Web, вместе с ним придут Jackson, logging библиотеки, validation integration и servlet-related артефакты. Это экономит работу, но может принести версия conflicts.

Version conflict возникает, когда два зависимость paths требуют разные версии одного артефакт. Инструменты сборки выбирают одну версия по своим resolution rules. Но tree все равно нужно понимать, потому что выбранная версия может сломать запуск приложения behavior.

Exclusions убирают нежелательные transitive зависимости. Version ranges разрешают гибкие версии, но ухудшают reproducibility и обычно не подходят для приложение сборкаs.

Последовательность шагов

  1. координатам.
  2. scopes.
  3. transitive зависимости.
  4. conflict resolution.
  5. зависимость tree.

Эта последовательность - картинка в голове, с которой нужно читать файлы сборки. Названия в Maven и Gradle отличаются, но практический вопрос одинаковый: какой входные данные используется, какая задача запускается, какой результат получается и где этот результат хранится.

Конкретный пример

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.7.4</version>
  <scope>запуск приложения</scope>
</dependency>

Полезная таблица

ПонятиеЗначение
compile / implementationНужна production code.
providedНужна для compile, поставляется server/запуск приложения.
запуск приложенияНужна при запуске приложения, не для compilation.
тестНужна только тест code.
systemLocal file зависимость; в нормальных проектах избегают.

Где это встречается в работе

Лучшая привычка - смотреть зависимость tree до догадок. В Maven используй mvn dependency:tree; в Gradle - ./gradlew dependencies или dependencyInsight.

В командной разработке знание сборки - не необязательная теория. Оно влияет на локальный development, время CI, зависимость upgrades, стабильность релиз и debugging. Когда Spring сервис не стартует после изменения зависимость, CI скачивает другую библиотека версия или артефакт не получается deployed, ответ обычно находится в сборка настройка, зависимость graph, упаковка step или репозиторий setup.

Частые ошибки

  • Копировать настройка, не понимая, на какой слой сборка она влияет.
  • Считать локально успешный сборка доказательством, что CI и production delivery тоже сработают.
  • Игнорировать зависимость trees, сгенерированный результат и репозиторий rules до момента failed релиз.
  • Смешивать приложение запуск приложения настройка и сборка-time настройка.

Чеклист понимания

  • Я могу объяснить главные terms этой статьи, не перечитывая сборка file вслух.
  • Я могу нарисовать последовательность от исходный код до артефакт для этой темы.
  • Я могу назвать command или file, который первым проверю при сборка problem.

Вопросы для самопроверки

  1. Какую проблему этот сборка concept решает в реальном Java или Spring проект?
  2. Какой file или command быстрее всего даст evidence, когда что-то ломается?
  3. Какая ошибка заставит сборка работать локально, но падать в CI или у другого разработчик?

Практика перед следующим уроком

Выберите любую зависимость в Java-проекте и откройте дерево зависимостей. Отметьте одну прямую зависимость и две транзитивные зависимости. Потом найдите одну версию, которая не написана напрямую в build-файле, и объясните, откуда она взялась.

Авторизуйтесь чтоб пройти тесты

Practice

Интерактивная практика

Выполните задания и сразу проверьте ответ.