Что такое аспектно-ориентированное программирование (AOP) в Spring
Что проверяют
Понимаете ли вы, что это способ вынести сквозную логику, и знаете ли, что в Spring оно работает через прокси со всеми вытекающими.
Как отвечать
Сквозная задача это то, что нужно во многих местах и не относится к предметной логике: транзакции, кэш, права, логирование, метрики, повторы. Копировать это по методам плохо, поэтому логику описывают отдельно и применяют к нужным местам декларативно.
Термины: аспект это класс со сквозной логикой; срез (pointcut) это выражение, отбирающее методы; совет (advice) это что делать (@Before, @After, @AfterReturning, @AfterThrowing, @Around); точка соединения это конкретный вызов.
@Aspect @Component
public class TimingAspect {
@Around("@annotation(Timed)")
public Object measure(ProceedingJoinPoint pjp) throws Throwable {
long t = System.nanoTime();
try { return pjp.proceed(); }
finally { log.info("{} занял {} мс", pjp.getSignature(), (System.nanoTime() - t) / 1_000_000); }
}
}Ключевое про реализацию: Spring AOP строится на прокси, поэтому работает только для публичных методов бинов и только при вызове снаружи. Самовызов внутри класса идёт мимо аспекта. Именно на этом механизме держатся @Transactional, @Cacheable, @Async и @PreAuthorize, и потому у всех у них одна и та же ловушка.
Если нужен перехват приватных методов или создания объектов, это уже AspectJ с вплетением в байт-код.
Где спотыкаются
Не знают, что самовызов проходит мимо аспекта.
Вешают аспект на приватный метод.
Забывают pjp.proceed() в @Around и молча отменяют вызов метода.
Пишут слишком широкий срез вроде «все методы всех бинов» и получают заметное замедление.