Паттерны Spring Framework

Spring не «состоит из GoF-паттернов», но многие механизмы удобно объяснять через знакомые роли.

Dependency Injection

Container создаёт object graph и передаёт зависимости:

@Service
class ReportService {
    private final ReportRepository repository;
 
    ReportService(ReportRepository repository) {
        this.repository = repository;
    }
}

Объект не ищет dependency сам. Это главное отличие от Service Locator.

См. Spring Dependency Injection и Inversion of Control.

Factory

BeanFactory и ApplicationContext создают и связывают beans по definitions. Factory здесь управляет не только вызовом constructor, но и scopes, post-processors и lifecycle.

См. Spring Context и Жизненный цикл бина.

Proxy

Transaction management, method security, caching и Spring AOP часто работают через proxy:

caller → proxy → advice → target bean

Отсюда следуют ограничения:

  • вызов должен пройти через proxy;
  • self-invocation обычно обходит advice;
  • private method нельзя перехватить обычным proxy-вызовом;
  • тип proxy влияет на доступный interface.

См. Spring AOP, Spring Proxy, Transactional.

Template Method и callback

JdbcTemplate фиксирует общий алгоритм:

получить connection
→ создать statement
→ выполнить
→ преобразовать rows через callback
→ закрыть resources
→ перевести exception

Клиент передаёт изменяемую часть — SQL и RowMapper, а framework выполняет повторяющуюся инфраструктурную работу.

Front Controller

DispatcherServlet принимает HTTP-запросы в Spring MVC и координирует handler mapping, adapter, exception resolvers и rendering.

См. Front Controller, MVC, Контроллеры Spring.

Adapter

Spring MVC поддерживает разные формы handler через adapters. Общая dispatch-логика не обязана знать детали каждого controller style.

Chain of Responsibility

Servlet filters, Spring Security filter chain, interceptors и argument resolvers образуют последовательности обработчиков. Важно понимать:

  • порядок;
  • возможность прервать chain;
  • что выполняется до и после следующего элемента;
  • как распространяется exception.

Singleton и Prototype scopes

Имена scopes похожи на паттерны, но не тождественны им:

  • singleton — один bean на context и bean name;
  • prototype — новый bean при каждом запросе у container.

Prototype dependency, однажды внедрённая в singleton constructor, сама не начнёт обновляться на каждый method call. Нужен provider/object factory или scoped proxy.

Вопросы для собеседования

  1. Почему @Transactional может не сработать при внутреннем вызове? Вызов не проходит через proxy.
  2. Где в MVC Front Controller? DispatcherServlet.
  3. Что в JdbcTemplate передаёт пользователь? Изменяемую часть через callbacks, например RowMapper.
  4. Singleton bean один на JVM? Нет, область — context и bean name.
  5. DI и Service Locator одинаковы? Нет: при DI зависимость передаётся объекту, locator ищется самим объектом.

Связанные заметки