middle
Что такое Spring AOP? Какие основные понятия в AOP?
AOP (Aspect-Oriented Programming) – парадигма программирования, позволяющая выделять сквозную функциональность (cross-cutting concerns) в отдельные модули. Сквозная функциональность – это логика, пронизывающая множество модулей: логирование, транзакции, безопасность, кэширование.
Основные понятия
| Понятие | Описание |
|---|---|
| Aspect (Аспект) | Модуль сквозной функциональности (класс с @Aspect) |
| Advice (Совет) | Действие, выполняемое аспектом в определённой точке |
| Join Point (Точка соединения) | Место в коде, где может быть применён advice (в Spring – всегда вызов метода) |
| Pointcut (Срез) | Выражение, определяющее, к каким join point применяется advice |
| Target object | Объект, к которому применяется аспект |
| Proxy | Объект-обёртка для перехвата вызовов |
| Weaving | Процесс связывания аспектов с объектами (в Spring – runtime через прокси) |
Пример аспекта
Пример
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("Вызов метода: " + methodName);
}
}
Синтаксис Pointcut
Пример
@Pointcut("execution(* com.example.service.*.*(..))") // все методы в пакете
@Pointcut("@annotation(com.example.Loggable)") // с определённой аннотацией
@Pointcut("within(@org.springframework.stereotype.Service *)") // все @Service
@Pointcut("bean(userService)") // конкретный бин
Как работает AOP в Spring
Spring AOP основан на прокси-объектах:
- JDK Dynamic Proxy – если бин реализует интерфейс
- CGLIB Proxy – если бин не реализует интерфейс (создаётся подкласс)
Self-invocation – главный подводный камень
Пример
@Service
public class MyService {
@Loggable
public void methodA() { }
public void methodB() {
this.methodA(); // AOP НЕ сработает -- вызов идёт напрямую, минуя прокси
}
}
На собеседовании: ключевые моменты – прокси-модель и проблема self-invocation. Частая ошибка – не знать, что AOP в Spring работает только на уровне прокси и не перехватывает внутренние вызовы (
this.method()).