В чем разница между фильтрами, интерсепторами и перехватчиками в Spring
Что проверяют
Понимаете ли вы, на каком уровне работает каждый механизм, и умеете ли выбрать подходящий.
Как отвечать
Три уровня, различающиеся тем, где они находятся в цепочке обработки запроса.
Фильтры это механизм спецификации сервлетов, а не самого Spring. Они работают до того, как запрос попадёт в главный сервлет-диспетчер, и после того, как ответ из него вернулся. Что это значит на практике:
- фильтр видит сырой запрос и ответ и может подменить их обёрткой, например чтобы прочитать тело или сжать вывод;
- фильтр не знает, какой контроллер обработает запрос: на этом уровне выбор ещё не сделан;
- фильтр перехватывает все запросы, включая статические файлы и те, для которых контроллера не нашлось.
Типичное применение: аутентификация, кросс-доменные заголовки, журналирование всех запросов, добавление идентификатора трассировки, сжатие.
Перехватчики это уже механизм Spring MVC. Они работают после выбора обработчика, поэтому знают, какой контроллер и метод будут вызваны, и могут читать его аннотации. Три точки: до вызова, после вызова и после полной отработки, включая отрисовку представления.
Типичное применение: проверка прав по аннотации на методе, замер времени обработки конкретного контроллера, подстановка общих атрибутов.
Аспекты работают на уровне вызова методов бинов и знают аргументы и возвращаемое значение. Это самый глубокий уровень, и он не связан с вебом вовсе: аспект одинаково применим и к контроллеру, и к сервису.
Типичное применение: транзакции, кэширование, повторы, журналирование параметров.
Правило выбора: чем ниже уровень, тем больше контекста и меньше охват. Нужно поймать всё подряд и работать с сырым запросом, значит фильтр. Нужно знать контроллер, значит перехватчик. Нужны аргументы метода, значит аспект.
Где спотыкаются
Пытаются узнать контроллер внутри фильтра.
Читают тело запроса в фильтре без обёртки, из-за чего контроллер получает пустой поток.
Реализуют транзакции перехватчиком вместо аспекта.
Не знают, что фильтры срабатывают и там, где контроллера нет вовсе.