Перейти к содержанию

Spring Framework

Spring - это IoC-контейнер, вокруг которого собраны модули для веба, данных, транзакций и безопасности. Контейнер живёт внутри приложения, а не на сервере: приложение само поднимает контекст и все бины.

Модули

  • Spring Core - IoC-контейнер, бины, DI, scope, жизненный цикл, Environment
  • Spring Boot - автоконфигурация, стартеры, встроенный сервер, Spring без Boot
  • Spring Web MVC - DispatcherServlet, контроллеры, REST, ошибки, фильтры, конфигурация
  • Spring Data - Spring Data JPA, Hibernate, репозитории, запросы, аудит
  • Транзакции в Spring - @Transactional, propagation, блокировки, retry, распределённые транзакции
  • Spring Security - аутентификация, авторизация, цепочка фильтров, JWT
  • Spring WebFlux
  • Spring Cloud

Spring и Java EE (Jakarta EE)

Главное различие одной фразой: в Java EE контейнер - часть сервера приложений, в Spring контейнер - часть самого приложения.

Java EE: сервер уже всё умеет, я описываю бины, ставлю @Inject, @EJB, @Resource, контейнер сам разрулит. Spring: я сам собираю приложение из бинов. Контейнер - конструктор, куда я стаскиваю всё нужное и контролирую поведение.


Кто хозяин: сервер или приложение

Java EE:

  • IoC - часть контейнера сервера приложений: WildFly, Payara, WebLogic, WebSphere, TomEE
  • war или ear деплоится внутрь готового окружения
  • DI даётся спецификациями: CDI (@Inject, @Named, @ApplicationScoped), @EJB, @Resource
  • контейнер создаёт и ведёт бины как часть сервера, жизненный цикл полностью у сервера

Spring:

  • IoC-контейнер - часть самого приложения
  • собирается jar (Spring Boot) и запускается: java -jar app.jar
  • внутри процесса поднимается ApplicationContext, он и создаёт бины
  • внешний сервер приложений не нужен, Tomcat или Jetty - встроенная библиотека
  • может работать и на Jakarta EE сервере как WAR (см. Spring без Boot)

Модель IoC и DI

Java EE (CDI):

  • DI стандартизован: jakarta.inject, jakarta.enterprise.cdi
  • @Inject для полей, конструкторов и сеттеров, @Qualifier для выбора реализации
  • scope: @RequestScoped, @SessionScoped, @ApplicationScoped
  • интерсепторы (@Interceptor, @AroundInvoke), декораторы, события
  • CDI видит только то, что считает CDI-бинами: архив, beans.xml, discovery mode

EJB - три вида бинов:

  • @Stateless - без состояния между вызовами
  • @Stateful - хранит состояние между вызовами одного клиента
  • @Singleton - один экземпляр на приложение

Spring:

  • свой контейнер: ApplicationContext поверх BeanFactory (см. Spring Core)
  • бины: @Component, @Service, @Repository, @Controller, @Bean
  • DI: @Autowired, @Qualifier, @Primary, через конструктор, сеттер или поле
  • scope через @Scope: singleton, prototype, request, session, application и свои кастомные
  • конфигурация Java-кодом (@Configuration), аннотациями и properties
  • свой AOP на прокси: @Transactional, @Async, @Cacheable
  • полный контроль жизненного цикла: @PostConstruct, @PreDestroy, BeanPostProcessor

Разница в подходе: спецификация Java EE задаёт минимум, остальное делает вендор сервера. В Spring всё под одной крышей, максимум возможностей в одном контейнере.


Связь с окружением

Java EE - контейнер сервера управляет:

  • транзакциями (JTA)
  • пулом соединений
  • JMS, JPA, security, JNDI-ресурсами
  • DI завязан на ресурсы сервера: @PersistenceContext, @Resource(lookup = "jdbc/..."), @EJB

Spring - сам поднимает:

  • DataSource (HikariCP и т.п.)
  • EntityManagerFactory
  • менеджер транзакций
  • JMS-шаблоны, Kafka-listeners и т.п.
  • всё настраивается внутри контекста, независимо от платформы

Сравнение

Spring Java EE / Jakarta EE (EJB, CDI)
Контейнер IoC-контейнер внутри приложения Контейнер сервера приложений
Деплой Jar (Boot) или WAR на любой сервер WAR или EAR на сервер приложений
Настройка Аннотации, Java-код, properties Стандарты Jakarta EE и настройки сервера
Ресурсы сервера (JNDI, DataSource) Свой пул, JNDI - только если настроить Нативно
Транзакции Spring Transaction Management или JTA Встроенный JTA сервера
Scope Гибкие, можно свои Заданы стандартом
Жизненный цикл Полностью настраивается У сервера

Итого:

  • Java EE IoC впаян в сервер приложений и его ресурсы
  • Spring IoC - самодостаточный контейнер, который запускается где угодно: jar, Docker, Kubernetes, обычный Tomcat