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

Первая программа на 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 APIHTTP-интерфейс: клиент шлёт GET/POST, сервер отвечает JSON (текст в фигурных скобках)
КонтроллерКласс, который принимает HTTP и вызывает сервис
СервисКласс с бизнес-логикой (правила, проверки) — без привязки к HTTP
Модель (DTO)Объект данных для ответа или запроса (Greeting с полями name, message)
MavenСборщик проекта: pom.xml перечисляет библиотеки, mvn скачивает их и компилирует код
TomcatВстроенный в Boot HTTP-сервер; по умолчанию порт 8080

Мы соберём маленький REST API с тремя слоями — модель → сервис → контроллер. Так же устроены крупные проекты: больше классов, те же роли.


Как Spring "видит" ваш код при старте

  1. Запускается DemoApplication.mainSpringApplication.run(...).
  2. Spring сканирует пакет com.example.demo и вложенные пакеты.
  3. Находит классы с @Service, @RestController и создаёт beans.
  4. Видит, что GreetingController просит GreetingService в конструкторе — создаёт сервис раньше и передаёт в контроллер.
  5. Поднимается 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 — первая программа.