Перейти к основному содержимому

Области зависимости Maven

· 4 мин. чтения

1. Обзор

Maven — один из самых популярных инструментов сборки в экосистеме Java, и одной из его основных функций является управление зависимостями.

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

2. Транзитивная зависимость

В Maven есть два типа зависимостей: прямые и транзитивные.

Прямые зависимости — это те, которые мы явно включаем в проект.

Их можно включить с помощью тегов <dependency> :

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

С другой стороны, транзитивные зависимости требуются прямыми зависимостями. Maven автоматически включает необходимые транзитивные зависимости в наш проект.

Мы можем перечислить все зависимости, включая транзитивные зависимости в проекте, с помощью команды mvn dependency:tree .

3. Области зависимости

Области действия зависимостей могут помочь ограничить транзитивность зависимостей. Они также изменяют путь к классам для различных задач сборки. Maven имеет шесть областей зависимостей по умолчанию.

И важно понимать, что каждая область действия — кроме импорта — влияет на транзитивные зависимости.

3.1. Компиляция

Это область по умолчанию, если не указана другая область.

Зависимости с этой областью доступны в пути к классам проекта во всех задачах сборки. Они также распространяются на зависимые проекты.

Что еще более важно, эти зависимости также транзитивны:

<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>

3.2. При условии

Мы используем эту область, чтобы отметить зависимости, которые должны быть предоставлены во время выполнения JDK или контейнером.

Хорошим вариантом использования для этой области будет веб-приложение, развернутое в каком-либо контейнере, где контейнер уже сам предоставляет некоторые библиотеки. Например, это может быть веб-сервер, который уже предоставляет API сервлетов во время выполнения.

В нашем проекте мы можем определить эти зависимости с предоставленной областью действия:

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

Предоставленные зависимости доступны только во время компиляции и в тестовом пути к классам проекта . Эти зависимости также не являются транзитивными.

3.3. Время выполнения

Зависимости с этой областью необходимы во время выполнения. Но они нам не нужны для компиляции кода проекта. Из-за этого зависимости, отмеченные областью выполнения , будут присутствовать в пути к классам среды выполнения и теста, но они будут отсутствовать в пути к классам компиляции.

Драйвер JDBC — хороший пример зависимостей, которые должны использовать область выполнения:

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<scope>runtime</scope>
</dependency>

3.4. Тест

Мы используем эту область, чтобы указать, что зависимость не требуется в стандартной среде выполнения приложения, а используется только в целях тестирования.

Тестовые зависимости не являются транзитивными и присутствуют только для тестовых и исполнительных путей к классам.

Стандартный вариант использования этой области — добавление тестовой библиотеки, такой как JUnit, в наше приложение:

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

3.5. Система

Системная область очень похожа на предоставленную область. Основное отличие состоит в том, что system требует, чтобы мы прямо указывали на определенный jar в системе.

Стоит отметить, что область действия системы устарела .

Важно помнить, что сборка проекта с зависимостями системной области может завершиться ошибкой на разных машинах, если зависимости отсутствуют или расположены в другом месте, чем указывает один systemPath :

<dependency>
<groupId>com.foreach</groupId>
<artifactId>custom-dependency</artifactId>
<version>1.3.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/custom-dependency-1.3.2.jar</systemPath>
</dependency>

3.6. импорт

Он доступен только для типа зависимости pom .

import указывает, что эта зависимость должна быть заменена всеми действующими зависимостями, объявленными в ее POM.

Здесь ниже зависимость пользовательского проекта будет заменена всеми зависимостями, объявленными в разделе pom.xml <dependencyManagement> пользовательского проекта .

<dependency>
<groupId>com.foreach</groupId>
<artifactId>custom-project</artifactId>
<version>1.3.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>

4. Объем и транзитивность

Каждая область зависимости влияет на транзитивные зависимости по-своему. Это означает, что разные транзитивные зависимости могут оказаться в проекте с разными областями.

Однако зависимости с предоставленными областями и тестом никогда не будут включены в основной проект.

Давайте подробно рассмотрим, что это означает:

  • Для области компиляции все зависимости с областью выполнения будут подтягиваться с областью выполнения в проекте, а все зависимости с областью компиляции будут подтягиваться с областью компиляции в проекте.
  • Для предоставленной области зависимости как среды выполнения , так и области компиляции будут включены в предоставленную область в проекте.
  • Для области тестирования транзитивные зависимости как времени выполнения , так и области компиляции будут включены в область тестирования в проекте.
  • Для области выполнения транзитивные зависимости как среды выполнения , так и области компиляции будут подтягиваться вместе с областью выполнения в проекте.

5. Вывод

В этой быстрой статье мы сосредоточились на областях зависимостей Maven, их назначении и деталях того, как они работают.

Чтобы углубиться в Maven, лучше всего начать с документации .