JavaRush /Курсы /Spring Boot /Spring Initializr и ...

Spring Initializr и параметры проекта

Spring Boot
3 уровень , 0 лекция
Открыта

1. Spring Initializr как старт проекта

Если вы когда-нибудь начинали проект «с нуля» в пустой директории, вы знаете эту стадию: пять минут уходят на создание папок, потом два часа — на выбор названия модуля, ещё час — на подключение зависимостей… а код приложения так и не появился. Для новичка это особенно неприятно: решений много, большинство выглядят одинаково, а ошибки проявляются позже. Spring Initializr существует именно для того, чтобы старт был быстрым, стандартным и воспроизводимым, а вы могли думать о приложении, а не о ритуалах.

Spring Initializr — это не «кнопка, которая делает магию», а генератор аккуратного шаблона, который фиксирует за вас типовые инженерные решения: структуру каталогов, build-файл, базовый класс приложения, минимальные зависимости и тестовый скелет. Это как набор «заводских настроек» для нового телефона: вы всё равно потом настроите его под себя, но стартовать с адекватной базы гораздо приятнее, чем с голого пластика.

Идея контейнера, component scanning и wiring уже понятна. Теперь всему этому нужен реальный дом — проект, который стартует без ручной сборки мира. Поэтому начинать приходится не с контроллера, а с правильного каркаса.

Важно уловить главное: в Boot-проекте всё начинается не с написания кода, а с выбора нескольких параметров. Они влияют на структуру проекта, на то, как Spring будет сканировать пакеты, как будет называться артефакт сборки и какую версию Java будет ожидать проект. Именно этим мы сейчас и займёмся.

2. Поля Initializr, которые важны

Когда вы открываете Spring Initializr, форма выглядит так, будто вас собираются принять на работу в NASA: много полей, списков, версий и загадочных слов. Хорошая новость: на старте нам нужно совсем немного. Остальное либо можно оставить по умолчанию, либо трогать позже, когда появится реальная причина, а не тревога уровня «вдруг пригодится».

Наша цель — получить проект catalog-service, который соответствует baseline курса: Java + Gradle + executable jar + Spring Boot 4.0.3, и при этом имеет нормальные имена, которые не стыдно видеть в логах, пакетах и файлах.

Ниже — практичная таблица: что означает каждое поле и что мы выбираем. Воспринимайте её как шпаргалку, чтобы не зависнуть на форме на 40 минут.

Поле в Initializr Что это значит по-человечески Что ставим для курса Почему так
Project Какой build tool будет управлять сборкой Gradle Курс строится вокруг Gradle; единый стиль снижает хаос
Language На каком языке будут исходники Java Без сюрпризов и лишнего усложнения
Spring Boot Версия Boot, под которую генерируем проект 4.0.3 Это фиксированный baseline курса
Group «Корневое пространство имён» и основа для базового Java-пакета com.example Классический нейтральный пример; важно понять принцип
Artifact Короткое имя проекта и будущего артефакта сборки catalog-service Предметное имя под домен курса: сервис каталога
Name Человекочитаемое имя проекта (часто = artifact) catalog-service Можно оставить как artifact, чтобы не плодить лишние варианты
Description Текстовое описание (влияние минимальное) что угодно короткое Главное — не превращать это в «эссе о смысле жизни»
Package name Базовый Java-пакет (можно руками) com.example.catalogservice Логично следует из group и artifact и хорошо читается
Packaging Формат упаковки приложения Jar Boot-сервис обычно живёт как исполняемый jar без внешнего сервера
Java Целевая версия Java проекта 25 Стабильный baseline курса и предсказуемость окружений

Здесь полезно держаться одной линии: Java 25 выбираем в Initializr и ту же версию потом закрепляем в сборке. Тогда IDE, Gradle и сам проект не будут спорить друг с другом о том, на какой JDK они живут.

3. group и artifact как основа пакетов

На словах group и artifact звучат как «какие-то метаданные для сборки», поэтому новичок легко думает: «Да какая разница, напишу test и поехали». Но разница есть, и она вполне практичная. Эти два поля влияют не только на то, как проект будет называться на диске, но и на то, как будут выглядеть ваши пакеты, а значит — как Spring будет искать ваши классы.

Spring Boot по умолчанию сканирует компоненты, начиная с пакета, где лежит главный класс приложения. Поэтому базовый пакет должен быть таким, чтобы в него естественно укладывался весь проект. Если случайно выбрать странный пакет или положить главный класс не туда, получится очень «весёлая» ситуация: классы вроде бы есть, аннотации вроде бы стоят, а Spring их «не видит».

Давайте посмотрим на примере:

# То, что вы вводите в форме Initializr:
group:    com.example
artifact: catalog-service

# То, что получится на выходе:
→ базовый пакет: com.example.catalogservice
→ имя проекта:   catalog-service

Почему catalogservice, а не catalog-service? Потому что в Java-пакетах нельзя использовать дефис. Initializr обычно «нормализует» имя, убирая дефисы.

Вот минимальная иллюстрация: строка package сверху файла берётся именно из выбранной пакетной базы.

package com.example.catalogservice;

/**
 * Здесь нам важен базовый пакет.
 * Сам класс пока пустой — структура проекта растёт именно от package,
 * а не от содержимого этого файла.
 */
public class CatalogServiceApplication {
    // Пока без логики.
}

Пока это просто пустой класс, и это нормально. Но именно из строки package ... дальше вырастет вся структура проекта.

Чтобы увидеть связь совсем явно, держите в голове простую схему:

flowchart TD
    %% group и artifact — это входные параметры (метаданные), которые задают «географию» проекта
    A["group: com.example"] --> C["base package: com.example.catalogservice"]
    B["artifact: catalog-service"] --> C

    %% Главный класс должен лежать в базовом пакете: от него стартует сканирование компонентов
    C --> D["CatalogServiceApplication в base package"]

    %% Дальше Spring «видит» все подпакеты (и компоненты внутри них), если они лежат ниже по дереву
    D --> E["component scan видит подпакеты: config, catalog, ..."]

Здесь не нужно пугаться слова scan: это всего лишь «Spring пробегается по пакетам и ищет классы, отмеченные как компоненты». А вы, выбирая group и artifact, по сути задаёте стартовую географию этого «пробега».

Ещё один практичный нюанс: artifact влияет на то, как будет называться ваш артефакт сборки. Когда вы будете собирать проект, итоговый jar часто получает имя вроде catalog-service-0.0.1-SNAPSHOT.jar. Это не главная тема сегодняшней лекции, но это ещё один повод выбрать короткое и понятное имя — чтобы потом не запускать файл с названием на три экрана.

4. Практические настройки проекта

Packaging: Jar и War

Слово packaging в Initializr звучит так, будто сейчас начнётся лекция по архиваторам. На деле всё проще: вы выбираете, в каком формате приложение будет собираться и запускаться. Для Spring Boot сегодня самый естественный путь — Jar, потому что Boot-приложение обычно живёт как самодостаточный сервис: запускается одной командой и поднимает встроенный сервер (embedded) внутри себя.

Формат War — это более старый (и всё ещё встречающийся) подход, когда приложение собирают как web archive, а затем деплоят во внешний сервер приложений. Для учебного курса по Boot это почти всегда лишняя ветка сложности: появляется внешний контейнер, появляются вопросы «куда деплоить», «какой сервер», «какая конфигурация» — и вы теряете ощущение, что приложение запускается как обычная программа.

Поэтому в этом курсе мы фиксируем простую и очень практичную идею: catalog-service должен быть исполняемым jar, который запускается как обычное приложение. Это хорошо укладывается в философию Boot: минимальный порог входа, одинаковое поведение в IDE и вне IDE и понятная модель «один сервис — один процесс».

Команды пока не важны: сначала нужно зафиксировать саму форму проекта. Здесь достаточно запомнить выбор: Packaging = Jar. Это решение не случайное, а методически полезное.

Версия Java в Initializr

Версия Java в форме Initializr выглядит как пункт из выпадающего списка, но последствия у неё очень реальные. Если выбрана одна версия, а реально проект собирается и запускается на другой, вы можете получить ошибки, которые новичку кажутся «рандомными». Например, IDE подчёркивает код красным, Gradle ругается на несовместимость, а приложение не стартует, хотя вы ничего «странного» не делали.

В нашем курсе мы выбираем Java 25 как целевую версию проекта. Это удобно не потому, что «цифра красивая», а потому, что проекту нужен один понятный baseline без разъехавшихся окружений.

Ещё один момент, который полезно понимать новичку: «версия Java» — это не только про то, какая JVM стоит на машине. Это ещё и то, какой bytecode будет генерироваться, какие API доступны и чего ожидает сборка. Выбор в Initializr — первый шаг к тому, чтобы эта версия стала частью проекта, а не «настроением вашей машины».

Если на машине несколько JDK, это само по себе не проблема. Проблема начинается, когда Initializr, IDE и сборка смотрят на разные версии. Тогда вы ловите ошибки, которые выглядят как «всё сломалось, хотя я ничего не менял».

Сегодня мы ограничимся простым правилом: выбрали Java 25 в Initializr — и дальше держимся этой линии, чтобы не устраивать себе сборочную лотерею.

Минимальная проверка после Generate

После того как вы выбрали параметры и нажали Generate, вы скачаете zip-архив. В этот момент у новичка часто возникает чувство: «Ну, архив скачался… а дальше что?» Дальше — небольшая проверка: важно убедиться, что каркас получился ровно в той форме, которую вы задали в Initializr. Полной экскурсии по дереву проекта здесь не нужно — пока достаточно опорных точек.

Пока достаточно проверить четыре вещи. Во‑первых, в src/main/java появился базовый пакет com/example/catalogservice. Во‑вторых, внутри него лежит главный класс приложения. Если в нём уже есть @SpringBootApplication и main(), всё в порядке: Boot entry point на месте. В‑третьих, в корне проекта есть build.gradle.kts, settings.gradle.kts, gradlew и папка src. В‑четвёртых, package name главного класса совпадает с той базой, которую вы собрали из group/artifact.

Этого пока достаточно. Нам не нужен глубокий разбор всей структуры проекта; важно лишь увидеть, что генерация не уехала в сторону и catalog-service стартует с ожидаемого каркаса.

5. Зависимости в Initializr

Самая коварная часть формы Initializr — список зависимостей. Там столько красивых слов, что хочется поставить галочки везде, будто вы набираете себе «скиллы» в RPG: «Web», «Security», «Data», «Cloud», «GraphQL»… Потом проект генерируется, и вы удивляетесь, почему он стартует 40 секунд, в логах тысяча строк, а вы пока хотели просто «Hello, world».

На старте важно придерживаться взрослого, скучного, но очень рабочего принципа: добавляем только то, что нужно для текущей учебной задачи. В нашем случае задача простая — создать каркас catalog-service, который уже является Boot-приложением и в будущем станет web-сервисом.

Поэтому в Initializr мы выбираем минимальный, понятный набор. Для курса разумно добавить зависимость для web-слоя. В форме Initializr она может называться просто Spring Web, а в build.gradle.kts у нас должна появиться точная зависимость org.springframework.boot:spring-boot-starter-webmvc. Это не значит, что нам уже сейчас нужен контроллер или подробный разбор HTTP. Пока достаточно того, что каркас проекта соответствует своей роли: это web-сервис, а не консольная программа, которая потом внезапно «перепрыгнет» в веб.

При этом важно сознательно не брать на старте всё подряд. Например, подключать Security «на всякий случай» — плохая идея: это отдельная дисциплина, и она заметно меняет поведение приложения. Аналогично не стоит хватать JPA и базу данных, потому что у нас проект по плану read-only и без БД. Даже если вы в будущем будете работать с данными, для этого есть отдельный курс, и мы туда сегодня не сворачиваем.

Ещё одна типичная «галочка-ловушка» — Lombok. Lombok может быть удобным, но для новичка он часто превращается в скрытую магию: вы не видите явного конструктора, не понимаете, откуда появились методы и в какой момент компилятор «подменил» вам класс. В этом курсе нам важно, чтобы код был максимально прозрачным. Так что если рука тянется поставить Lombok — это нормальный рефлекс, но мы его аккуратно придержим.

В итоге правильная психология такая: Initializr — это не меню ресторана, где нужно «попробовать всё», а касса в аэропорту: берём только то, что нужно для полёта, а чемоданы с лишними вещами оставляем дома.

6. Типичные ошибки при выборе параметров в Spring Initializr

Ошибка №1: случайный group вроде test, myapp или java.
Соблазн понятный: хочется быстрее перейти к коду. Но group влияет на базовый пакет, а пакет — на то, как Spring будет искать ваши компоненты. Случайный group потом начинает выглядеть странно в каждом файле (package test.catalogservice;), и в какой-то момент вы захотите всё переименовать. Лучше сразу выбрать нормальную, нейтральную схему вроде com.example и держаться её в рамках курса.

Ошибка №2: слишком длинный или «креативный» artifact.
artifact влияет на имя проекта, артефакта сборки и часто на массу автоматических мест (папки, настройки IDE, команды). Если вы назвали проект super-mega-ultra-catalog-service-for-my-future-startup, вы будете печатать это руками в неожиданных местах и проклинать себя на каждом шаге. Хороший artifact — короткий, предметный, без лишних слов: catalog-service как раз из этой категории.

Ошибка №3: выбрать Packaging = War, потому что «я где-то видел, что так бывает».
WAR — это отдельная модель деплоя во внешний сервер приложений. Для учебного Boot-проекта это чаще всего означает лишнюю сложность и путаницу «почему оно запускается не так». В рамках курса нам нужен самодостаточный сервис, поэтому Jar — правильный и простой выбор.

Ошибка №4: выбрать версию Java «какую угодно», а потом удивляться конфликтам окружения.
Если вы поставили в Initializr одну версию, а IDE/сборка живут в другой, вы ловите ошибки, которые выглядят как «всё сломалось, хотя я ничего не менял». В учебном проекте лучше держаться выбранного baseline (у нас это Java 25) и не менять версию без осознанной причины.

Ошибка №5: поставить слишком много зависимостей «на будущее».
Когда вы выбираете сразу web, security, data, cloud и ещё пять стартеров, проект превращается в тяжёлый комбайн, который ведёт себя «не так», как вы ожидаете. На старте мы берём минимально нужное для каркаса (в нашем случае — web-зависимость под будущий сервис) и не пытаемся решить задачи, которых ещё нет. Это экономит и время, и нервы, и качество понимания.

1
Задача
Spring Boot, 3 уровень, 0 лекция
Недоступна
Генерация starter-проекта с базовым пакетом по `group` и `artifact`
Генерация starter-проекта с базовым пакетом по `group` и `artifact`
1
Задача
Spring Boot, 3 уровень, 0 лекция
Недоступна
Скрипт загрузки проекта с явным `packageName`
Скрипт загрузки проекта с явным `packageName`
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ