← Назад к вопросам
Что такое Scope зависимости?
2.0 Middle🔥 141 комментариев
#SOLID и паттерны проектирования#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Scope зависимостей в Maven и Gradle
Scope (область видимости) зависимости определяет, на каких этапах сборки проекта и на какие другие проекты распространяется эта зависимость. Это один из ключевых механизмов управления зависимостями в Java проектах.
Основные Scopes в Maven
1. compile (по умолчанию)
<!-- Зависимость доступна на всех classpath и компилируется в JAR/WAR -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>compile</scope> <!-- или опустить, так как это значение по умолчанию -->
</dependency>
Когда используется:
- Нужна в основном коде приложения
- Нужна в production среде
- Компилируется в финальный артефакт (JAR/WAR)
Примеры:
- Spring Framework
- Lombok
- Jackson
- Apache Commons
2. test
<!-- Зависимость используется только для тестов -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
Когда используется:
- Используется только в тестовом коде (
src/test/java) - НЕ компилируется в финальный артефакт
- Доступна только при запуске тестов
Примеры:
- JUnit
- Mockito
- Testcontainers
- AssertJ
Структура проекта:
src/
├── main/java/ (test зависимости НЕ видны здесь)
└── test/java/ (test зависимости видны здесь)
3. provided
<!-- Зависимость предоставляется runtime окружением -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
Когда используется:
- Используется в коде, но предоставляется контейнером (Tomcat, JBoss и т.д.)
- НЕ компилируется в WAR файл
- Нужна при компиляции, но не нужна в production
Примеры:
- javax.servlet-api (Tomcat содержит свою реализацию)
- Java EE APIs
- Application server specific libs
Разница между compile и provided:
// Код использует Servlet API
public class MyServlet extends HttpServlet {
// HttpServlet из javax.servlet
}
// Если scope=compile: HttpServlet включается в WAR
// Если scope=provided: HttpServlet НЕ включается в WAR
// (Tomcat предоставит свою версию при runtime)
4. runtime
<!-- Зависимость нужна только при выполнении, не нужна при компиляции -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.1</version>
<scope>runtime</scope>
</dependency>
Когда используется:
- НЕ нужна при компиляции
- Нужна при запуске приложения
- Не должна быть указана в import statements
Примеры:
- JDBC драйверы (PostgreSQL, MySQL, MongoDB)
- Runtime логирование имплементации (SLF4J)
- Конфигурационные файлы
// Вы пишете код используя интерфейсы
DriverManager.getConnection("jdbc:postgresql://localhost/db");
// PostgreSQL драйвер (postgresql dependency) нужен только при runtime
// чтобы DriverManager знал как подключиться
// Если scope=compile: PostgreSQL jar включится в приложение
// Если scope=runtime: PostgreSQL jar НЕ включится в приложение
// но должен быть в classpath при запуске
5. system
<!-- Зависимость на локальном файловой системе -->
<dependency>
<groupId>com.local</groupId>
<artifactId>my-local-lib</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/my-local-lib.jar</systemPath>
</dependency>
Когда используется:
- Локальная JAR которая не в репозитории
- Редко используется в современных проектах
- Проблемы с портативностью
6. import (только для POM файлов)
<!-- Используется для наследования зависимостей из другого POM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Таблица всех Scopes
| Scope | Compile | Test | Runtime | Примеры |
|---|---|---|---|---|
| compile | ✓ | ✓ | ✓ | Spring, Guava |
| test | ✗ | ✓ | ✗ | JUnit, Mockito |
| provided | ✓ | ✓ | ✗ | servlet-api |
| runtime | ✗ | ✓ | ✓ | JDBC драйверы |
| system | ✓ | ✓ | ✗ | Локальные JAR |
| import | (POM только) | Bill of Materials |
Практические примеры pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0</version>
<dependencies>
<!-- COMPILE: основная бизнес-логика -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.0</version>
<!-- scope=compile (по умолчанию) -->
</dependency>
<!-- COMPILE: утилиты -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- PROVIDED: сервлет API (предоставляется Tomcat) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- RUNTIME: JDBC драйвер -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.1</version>
<scope>runtime</scope>
</dependency>
<!-- TEST: фреймворк для тестирования -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- TEST: моки -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>
<!-- TEST: Spring для тестов -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Scopes в Gradle
dependencies {
// COMPILE (по умолчанию)
implementation 'org.springframework.boot:spring-boot-starter-web:3.0.0'
// TEST
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.0.0'
// PROVIDED (обычно используется compileOnly)
compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
// RUNTIME
runtimeOnly 'org.postgresql:postgresql:42.5.1'
// Для классов используемых в тестах из основного кода
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.0'
}
Реальные ошибки Scope
Ошибка 1: compile вместо test
<!-- ПЛОХО -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<!-- Без scope (по умолчанию compile) -->
</dependency>
Проблема: JUnit включится в production JAR (ненужный вес)
<!-- ХОРОШО -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope> <!-- Только для тестов -->
</dependency>
Ошибка 2: provided вместо compile
<!-- ПЛОХО -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>provided</scope> <!-- Где будет предоставлена? -->
</dependency>
Проблема: Guava не предоставляется контейнером, приложение упадёт
<!-- ХОРОШО -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<!-- scope=compile (по умолчанию) -->
</dependency>
Как выбрать правильный Scope?
// Спроси себя:
// 1. Нужна ли эта зависимость в production?
// ДА → compile (или runtime если не нужна при компиляции)
// НЕТ → test или provided
// 2. Это сервис или API, предоставляемые контейнером?
// ДА → provided
// НЕТ → compile
// 3. Это только для тестов?
// ДА → test
// НЕТ → compile, runtime или provided
// 4. Нужна только при запуске, не при компиляции?
// ДА → runtime
// НЕТ → compile
Проверка зависимостей
# Вывести дерево зависимостей
mvn dependency:tree
# Вывести с указанием scope
mvn dependency:tree -DoutputFile=dependencies.txt
# Найти зависимости с конфликтами версий
mvn enforcer:enforce
# Анализ неиспользуемых зависимостей
mvn dependency:analyze
Bill of Materials (BOM)
<!-- Централизованное управление версиями через import scope -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Теперь все Spring Cloud зависимости унифицированы -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<!-- version не нужна, возьмётся из BOM -->
</dependency>
</dependencies>
Итого
- compile (default) — основной код, включается в JAR
- test — только для тестов, НЕ включается в JAR
- provided — предоставляется контейнером, НЕ включается в JAR
- runtime — не нужна при компиляции, только при запуске
- system — редко используется, локальная JAR
- import — для BOM файлов
Правильное использование Scopes снижает размер артефактов и избегает конфликтов зависимостей.