Ответ
Scope в Maven определяет жизненный цикл зависимости и её видимость (включается ли она в classpath) для различных этапов сборки, тестирования и выполнения проекта.
Основные значения scope:
| Scope | Описание | Включается в classpath для... | Пример использования |
|---|---|---|---|
compile |
(По умолчанию) Зависимость доступна на всех этапах. | Компиляции, тестов, выполнения. | spring-core, lombok. |
provided |
Зависимость предоставляется средой выполнения (JDK, контейнер сервлетов). | Компиляции и тестов, но не для сборки исполняемого артефакта (WAR/JAR). | servlet-api, javax.annotation-api. |
runtime |
Зависимость не нужна для компиляции, но требуется во время выполнения. | Тестов и выполнения, но не для компиляции. | JDBC-драйвер базы данных (например, mysql-connector-java). |
test |
Зависимость нужна только для фазы тестирования. | Только для компиляции и запуска тестов (src/test/java). |
junit, mockito. |
system |
Аналогичен provided, но требует явного указания пути к JAR-файлу в системе. |
Компиляции и тестов. Используется редко, так как делает сборку непереносимой. | Внутренние, неопубликованные библиотеки. |
import |
Используется только в секции <dependencyManagement> для импорта зависимостей из другого POM (обычно BOM). |
Не определяет classpath. Управляет версиями. | Импорт Spring Boot BOM: spring-boot-dependencies. |
Пример объявления в pom.xml:
<dependencies>
<!-- Зависимость только для тестов -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<!-- Зависимость, предоставляемая контейнером (Tomcat) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Практическое влияние: Scope влияет на содержимое итоговых артефактов (JAR/WAR). Например, зависимости с provided и test не будут включены в WEB-INF/lib WAR-файла.
Ответ 18+ 🔞
А, ну ты про scope в Maven спрашиваешь? О, это, блядь, классика! Сидит такой новичок, накидывает в pom.xml зависимости, а потом у него артефакт размером с дирижабль, потому что он, сука, junit на продакшен затащил. Пиздец, а не сборка.
Смотри сюда, я тебе на пальцах, но с технической точностью, объясню, что это за зверь такой — scope. Это, грубо говоря, указание Maven'у, когда и куда воткнуть твою библиотеку. Чтобы не тащить в продакшен то, что нужно только для тестов, понимаешь? Экономия места и нервов.
Основные значения, которые тебе надо знать, чтобы не выглядеть мудаком:
| Scope | Суть вопроса | Когда в classpath? | Где применяется? |
|---|---|---|---|
compile |
(Дефолтный, если не указал) Всё включено, брат. | Везде: компиляция, тесты, запуск. | Ну, spring-core, lombok — без них проект — говно. |
provided |
«Не трогай, у меня своя есть!» Среда выполнения (Tomcat, JDK) уже принесёт. | На компиляции и в тестах. В финальный JAR/WAR — НЕ лезет. | servlet-api. Ты же не будешь таскать его в WAR, когда Tomcat свой подсунет? |
runtime |
«На компиляции не нужен, но чтобы работало — воткни». | В тестах и при запуске. На компиляции — не видно. | JDBC-драйвер (mysql-connector). Интерфейсы ты скомпилировал с javax.sql, а вот саму железяку для подключения дай на runtime. |
test |
«Только для извращений в src/test». |
Только для компиляции и запуска тестов. В продакшен — ни-ни. | junit, mockito. Представь, если бы @Test летел на боевой сервер — ёперный театр! |
system |
«Вот тут лежит, ищи сам». Хуйня полная, непереносимая. | Компиляция, тесты. | Какая-нибудь левая company-secret-superlib.jar с жёстким путём. Используй, только если совсем еблан. |
import |
«Я не библиотека, я — начальник!» Только в <dependencyManagement>. |
Никуда не включается. Управляет версиями из BOM. | Импорт spring-boot-dependencies, чтобы версии не конфликтовали. |
Вот, смотри, как в деле выглядит, код не трогаю, он святой:
<dependencies>
<!-- Это только для тестов, нахуй! -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<!-- Это Tomcat сам даст, не суй в WAR, оболтус! -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
А на практике: если scope проёбан, получишь либо толстенный артефакт, либо ClassNotFoundException на боевом. Всё просто: test и provided в итоговую сборку не попадают. Остальные — пожалуйста. Главное — думай, блядь, головой, что куда ты пихаешь.