Первая программа на Spring Framework
Play ITЗагрузка интерактивного демо…
Первая программа на Spring Framework
Для кого эта глава
Вы уже писали main и классы на Java (первая программа, ООП). Здесь тот же язык, но приложение само поднимает веб-сервер и само связывает классы — вам не нужно вручную создавать new GreetingService() в main.
Если слова bean, контроллер, REST пока пустые — начните с таблицы ниже, затем идите по разделам по порядку.
Пошаговый проект "Simple CRM" (веб + REST + SQLite + JPA): Практикум Spring Boot — Simple CRM. Расширенный кейс с тестами — "Spring Boot приложение".
Архитектурный контекст слоёв — паттерны проектирования; цепочка фильтров и обработчиков — Chain of Responsibility в Java.
Где применяют Spring
После базового Java типичный следующий шаг на JVM — Spring Boot:
- встроенный веб-сервер (Tomcat);
- DI (внедрение зависимостей);
- REST API без ручного XML.
| Термин | Что это простыми словами |
|---|---|
| Spring Framework | "Контейнер" приложения: создаёт объекты (beans), знает, кто от кого зависит, подключает веб, БД, безопасность |
| Spring Boot | Надстройка: стартовые зависимости, автонастройка, одна команда mvn spring-boot:run — и сервер слушает порт |
| Bean | Объект, которым управляет Spring (обычно один экземпляр на тип в рамках приложения) |
| DI (Dependency Injection) | Spring передаёт зависимости в конструктор или поле; вы описываете классы, контейнер собирает граф |
| REST API | HTTP-интерфейс: клиент шлёт GET/POST, сервер отвечает JSON (текст в фигурных скобках) |
| Контроллер | Класс, который принимает HTTP и вызывает сервис |
| Сервис | Класс с бизнес-логикой (правила, проверки) — без привязки к HTTP |
| Модель (DTO) | Объект данных для ответа или запроса (Greeting с полями name, message) |
| Maven | Сборщик проекта: pom.xml перечисляет библиотеки, mvn скачивает их и компилирует код |
| Tomcat | Встроенный в Boot HTTP-сервер; по умолчанию порт 8080 |
Мы соберём маленький REST API с тремя слоями — модель → сервис → контроллер. Так же устроены крупные проекты: больше классов, те же роли.
Как Spring "видит" ваш код при старте
- Запускается
DemoApplication.main→SpringApplication.run(...). - Spring сканирует пакет
com.example.demoи вложенные пакеты. - Находит классы с
@Service,@RestControllerи создаёт beans. - Видит, что
GreetingControllerпроситGreetingServiceв конструкторе — создаёт сервис раньше и передаёт в контроллер. - Поднимается Tomcat; регистрируются маршруты из
@GetMapping.
Вы пишете что должно быть в системе; Spring решает в каком порядке создать объекты.
Перед стартом: JDK 17+, Maven, пройденные коллекции и базовый ООП желательны. Обзор всей экосистемы — Spring Framework. На Kotlin тот же стек возможен, но пример здесь на Java; сервер на Kotlin — Ktor.
Что получится
- Maven-проект из start.spring.io;
- запуск:
mvn spring-boot:run;
mvn spring-boot:run
Разбор:
- Здесь показан воспроизводимый сценарий команд
mvnдля проверки темы раздела на реальном запуске. - Команды идут как цепочка шагов: подготовка окружения, вызов инструмента и проверка ответа/результата.
- Такой блок полезен тем, что его можно выполнить без IDE и быстро подтвердить, что пример живой.
- Если результат отличается от ожидаемого, причина почти всегда в окружении или порядке выполнения строк.
- Практически этот же набор команд переносится в CI как smoke-проверка документационного примера.
HTTP GET /greet/Алексей
→ GreetingController (@RestController)
→ GreetingService (@Service, бизнес-правила)
→ Greeting (модель → JSON)
Разбор:
- Этот блок работает как схема: строка
HTTP GET /greet/Алексейзадаёт каркас потока без деталей реализации. - Сначала видна общая последовательность этапов, а затем уже разбираются конкретные классы и методы.
- Такой формат уменьшает когнитивную нагрузку и помогает быстрее локализовать проблемный шаг.
- Практически это карта для отладки и чтения следующих кодовых фрагментов.
Код ITЗагрузка примера кода…
Разбор:
- Здесь показан воспроизводимый сценарий команд
curl`, `-d`, `-o`, `unzip`, `cdдля проверки темы раздела на реальном запуске. - Команды идут как цепочка шагов: подготовка окружения, вызов инструмента и проверка ответа/результата.
- Такой блок полезен тем, что его можно выполнить без IDE и быстро подтвердить, что пример живой.
- Если результат отличается от ожидаемого, причина почти всегда в окружении или порядке выполнения строк.
- Практически этот же набор команд переносится в CI как smoke-проверка документационного примера.
mvn spring-boot:run
# http://localhost:8080
Разбор:
- Здесь показан воспроизводимый сценарий команд
mvnдля проверки темы раздела на реальном запуске. - Команды идут как цепочка шагов: подготовка окружения, вызов инструмента и проверка ответа/результата.
- Такой блок полезен тем, что его можно выполнить без IDE и быстро подтвердить, что пример живой.
- Если результат отличается от ожидаемого, причина почти всегда в окружении или порядке выполнения строк.
- Практически этот же набор команд переносится в CI как smoke-проверка документационного примера.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Разбор:
- В этом фрагменте ключевой объект —
DemoApplication; через него показан конкретный кусок архитектуры из раздела. - Аннотации
@SpringBootApplicationвключают фреймворковое поведение — регистрация, биндинг, security или тестовая инфраструктура. - Основной поток строится на вызовах
main()`, `run(): они задают путь от входа к результату. - При расширении этого примера сначала проверяют контракты методов и тесты на граничные случаи — именно там чаще всего возникает регрессия.
Код ITЗагрузка примера кода…
Разбор:
- В этом фрагменте ключевой объект —
Greeting; через него показан конкретный кусок архитектуры из раздела. - Аннотации
@Dataвключают фреймворковое поведение — регистрация, биндинг, security или тестовая инфраструктура. - Основной поток строится на вызовах
Greeting()`, `getMessage(): они задают путь от входа к результату. - По
returnвидно, какой итог выходит наружу: объект домена, HTTP-ответ или конфигурационный результат. - При расширении этого примера сначала проверяют контракты методов и тесты на граничные случаи — именно там чаще всего возникает регрессия.
Код ITЗагрузка примера кода…
Разбор:
- В этом фрагменте ключевой объект —
GreetingService; через него показан конкретный кусок архитектуры из раздела. - Аннотации
@Serviceвключают фреймворковое поведение — регистрация, биндинг, security или тестовая инфраструктура. - Основной поток строится на вызовах
createGreeting()`, `trim()`, `isEmpty()`, `Greeting(): они задают путь от входа к результату. - Условия
ifв этом блоке явно отделяют валидный и невалидный сценарий, чтобы ошибка отрабатывала до выполнения основной операции. - По
returnвидно, какой итог выходит наружу: объект домена, HTTP-ответ или конфигурационный результат. - При расширении этого примера сначала проверяют контракты методов и тесты на граничные случаи — именно там чаще всего возникает регрессия.
Код ITЗагрузка примера кода…
Разбор:
- В этом фрагменте ключевой объект —
GreetingController; через него показан конкретный кусок архитектуры из раздела. - Аннотации
@RestController, @Autowired, @GetMapping, @PathVariableвключают фреймворковое поведение — регистрация, биндинг, security или тестовая инфраструктура. - Основной поток строится на вызовах
GreetingController()`, `GetMapping()`, `greet()`, `createGreeting(): они задают путь от входа к результату. - По
returnвидно, какой итог выходит наружу: объект домена, HTTP-ответ или конфигурационный результат. - При расширении этого примера сначала проверяют контракты методов и тесты на граничные случаи — именно там чаще всего возникает регрессия.
Браузер или curl: GET /greet/Алексей
→ Tomcat принимает соединение
→ DispatcherServlet (центральный обработчик Spring MVC)
→ HandlerMapping выбирает метод greet в GreetingController
→ (при необходимости) перехватчики preHandle → контроллер → postHandle
→ greetingService.createGreeting("Алексей")
→ объект Greeting → JSON в теле ответа, статус 200
→ afterCompletion у перехватчиков
Полная схема с фильтрами, перехватчиками и этапами рендеринга — в разделе "Жизненный цикл запроса в Spring Boot" статьи про Spring Framework.
Разбор:
- Этот блок работает как схема: строка
Браузер или curl: GET /greet/Алексейзадаёт каркас потока без деталей реализации. - Сначала видна общая последовательность этапов, а затем уже разбираются конкретные классы и методы.
- Такой формат уменьшает когнитивную нагрузку и помогает быстрее локализовать проблемный шаг.
- Практически это карта для отладки и чтения следующих кодовых фрагментов.
{
"message": "Привет",
"name": "Алексей"
}
Разбор:
- JSON-поля
message`, `nameзадают контракт обмена между клиентом и сервером в этом сценарии. - Такой пример нужен, чтобы точно понимать форму payload и не гадать, какие данные сериализуются.
- Любое изменение имени поля требует синхронизации с клиентами и тестами, иначе появятся ошибки интеграции.
- На практике этот блок становится образцом для API-тестов и примеров в документации.
server.port=8080
logging.level.root=INFO
spring.application.name=first-spring-app
Разбор:
- В
.propertiesздесь важны ключиserver.port`, `logging.level.root`, `spring.application.name: именно они управляют поведением приложения при старте. - Формат плоский, поэтому каждую строку легко сопоставить с эффектом в логах и поведении endpoint-ов.
- Этот способ конфигурации удобен для быстрых изменений и отладки без перекомпиляции.
- Типичный риск — опечатка в ключе: файл валиден, но параметр не читается фреймворком.
server:
port: 8080
logging:
level:
root: INFO
spring:
application:
name: first-spring-app
Разбор:
- Ключи
server`, `port`, `logging`, `level`, `root`, `springзадают runtime-поведение через конфигурацию, а не через изменения в коде. - Отступы формируют иерархию параметров, поэтому структура файла влияет на то, какие настройки реально применятся.
- Фрагмент полезен как точка контроля окружения — порт, логирование, имя сервиса или security-параметры.
- На практике такие блоки связывают с профилями и переменными окружения для dev/test/prod.
@PostMapping("/greet")
public Greeting postGreet(@RequestBody Greeting request) {
return greetingService.createGreeting(request.getName());
}
Разбор:
- Этот фрагмент показывает рабочую Java-логику, где важен не синтаксис сам по себе, а порядок действий и ответственность кода.
- Аннотации
@PostMapping, @RequestBodyвключают фреймворковое поведение — регистрация, биндинг, security или тестовая инфраструктура. - Основной поток строится на вызовах
PostMapping()`, `postGreet()`, `createGreeting()`, `getName(): они задают путь от входа к результату. - По
returnвидно, какой итог выходит наружу: объект домена, HTTP-ответ или конфигурационный результат. - При расширении этого примера сначала проверяют контракты методов и тесты на граничные случаи — именно там чаще всего возникает регрессия.
mvn spring-boot:run
# http://localhost:8080/greet/Имя
Разбор:
- Здесь показан воспроизводимый сценарий команд
mvnдля проверки темы раздела на реальном запуске. - Команды идут как цепочка шагов: подготовка окружения, вызов инструмента и проверка ответа/результата.
- Такой блок полезен тем, что его можно выполнить без IDE и быстро подтвердить, что пример живой.
- Если результат отличается от ожидаемого, причина почти всегда в окружении или порядке выполнения строк.
- Практически этот же набор команд переносится в CI как smoke-проверка документационного примера.
curl -s http://localhost:8080/greet/Алексей
Разбор:
- Здесь показан воспроизводимый сценарий команд
curlдля проверки темы раздела на реальном запуске. - Команды идут как цепочка шагов: подготовка окружения, вызов инструмента и проверка ответа/результата.
- Такой блок полезен тем, что его можно выполнить без IDE и быстро подтвердить, что пример живой.
- Если результат отличается от ожидаемого, причина почти всегда в окружении или порядке выполнения строк.
- Практически этот же набор команд переносится в CI как smoke-проверка документационного примера.
В подборках
Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:
Первые шаги (маршрут подборки) — Первая программа на JavaBean, Первая программа на JavaFX, Первая программа на JavaServer Faces, EF Core — первая программа, Первая программа на FastAPI, ADO.NET / Dapper — первая программа.