Как применяется аспектно-ориентированное программирование (AOP)
Что проверяют
Понимаете ли вы, что AOP выносит сквозную логику, и знаете ли ограничения реализации через прокси.
Как отвечать
Сквозная задача это то, что нужно во многих местах и не относится к предметной логике: транзакции, кэш, права, логирование, метрики, повторы, аудит. Копировать это по методам плохо, поэтому логика описывается отдельно и применяется декларативно.
Термины: аспект это класс со сквозной логикой, срез отбирает методы выражением, совет говорит, что делать (@Before, @After, @AfterReturning, @AfterThrowing, @Around).
@Aspect @Component
class RetryAspect {
@Around("@annotation(Retryable)")
Object retry(ProceedingJoinPoint pjp) throws Throwable {
for (int i = 0; ; i++) {
try { return pjp.proceed(); }
catch (TransientException e) { if (i == 2) throw e; }
}
}
}Где это используется в обычном проекте, даже если аспекты не пишут руками: на AOP построены @Transactional, @Cacheable, @Async, @PreAuthorize, @Retryable. То есть механизм работает у всех, просто аспекты уже написаны.
Ограничения Spring AOP: перехват только публичных методов бинов и только при вызове снаружи. Самовызов внутри класса идёт мимо. Нужен перехват приватных методов или конструкторов, значит AspectJ с вплетением в байт-код.
Где спотыкаются
Не знают, что самовызов проходит мимо аспекта.
Забывают pjp.proceed() в @Around и молча отменяют вызов.
Пишут срез вида «все методы всех бинов» и получают заметное замедление.
Прячут в аспект бизнес-логику, из-за чего поведение перестаёт читаться по коду.