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