Що таке AOP (Aspect-Oriented Programming)?
4. Статичні Pointcut → швидше динамічних 5. Уникайте стану в аспектах (Singleton!) 6. @Around → не забудьте pjp.proceed()
🟢 Junior Level
AOP — спосіб додати загальну функціональність (логування, транзакції) до багатьох класів, не змінюючи їх код.
Проста аналогія: Уявіть, що ви хочете записувати кожен дзвінок у компанії. Замість того щоб просити кожного співробітника вести журнал, ви ставите автоматичний запис усіх дзвінків.
// Без AOP:
public void save() {
log.info("Початок"); // Повторюється скрізь
repository.save(entity);
log.info("Кінець");
}
// З AOP:
@LogExecution // ← Одна анотація!
public void save() {
repository.save(entity);
}
Навіщо:
- Прибирає дублювання коду
- Бізнес-логіка окремо, інфраструктура окремо
- Легко увімкнути/вимкнути
🟡 Middle Level
Spring AOP vs AspectJ
| Spring AOP | AspectJ | |
|---|---|---|
| Як | Проксі в рантаймі | Зміна байт-коду |
| Що може | Тільки public методи | Методи, поля, конструктори |
| Self-invocation | ❌ Не працює | ✅ Працює |
| Складність | Простий | Складне налаштування |
Spring AOP працює тільки з Spring-бінами (виклики через проксі). AspectJ працює з будь-якими об’єктами, т.к. впроваджується на рівні байт-коду (compile-time або load-time weaving).
Терміни AOP
Aspect (Аспект) = модуль наскрізної логіки
Pointcut (Точка) = де застосовувати (вираз)
Advice (Порада) = що робити (логіка)
Join Point (Точка з'єднання) = конкретний метод
Типи Advice
@Before // До методу
@After // Після методу (завжди)
@AfterReturning // Після успішного
@AfterThrowing // При виключенні
@Around // Замість методу (найпотужніший)
Приклад аспекту
@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(LogExecution)")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
try {
return pjp.proceed(); // Виклик оригінального методу
} finally {
long duration = System.currentTimeMillis() - start;
log.info("Виконано за " + duration + "ms");
}
}
}
🔴 Senior Level
Interceptor Chain
Виклик методу → ReflectiveMethodInvocation:
1. SecurityInterceptor → перевірка прав
2. TransactionInterceptor → транзакція
3. CacheInterceptor → кеш
4. LoggingAspect → логування
5. Target method → ваш код
→ Кожен повертає результат або кидає exception
→ Порядок визначається через @Order
Продуктивність
Оверхед AOP:
→ Створення MethodInvocation об'єкта
→ Прохід по списку інтерцепторів
→ Рефлексія або прямий виклик
→ ~1-5 мкс на виклик
→ У Highload (1M RPS) → помітно!
Spring 6 + Virtual Threads
`synchronized` (ключове слово) в аспектах → Pinning віртуальних потоків!
→ Перевірте, чи не блокують ваші аспекти системні потоки
Production Experience
Повний приклад з
Aroundбезproceed()— у файлі [[16. Що таке аспект, advice, pointcut, join point]].
Best Practices
- Spring AOP → 95% випадків
- AspectJ → приватні методи, поля
- @Order → порядок аспектів
- Статичні Pointcut → швидше динамічних
- Уникайте стану в аспектах (Singleton!)
- @Around → не забудьте pjp.proceed()
Резюме для Senior
- AOP = наскрізна функціональність без дублювання
- Spring AOP = проксі, AspectJ = байт-код
- Interceptor Chain → порядок через @Order
- Оверхед ~1-5 мкс на виклик
- Pinning → обережно з synchronized в аспектах
- pjp.proceed() → обов’язково в @Around
🎯 Шпаргалка для інтерв’ю
Обов’язково знати:
- AOP = наскрізна функціональність (логування, транзакції, кеш) без дублювання коду
- Spring AOP працює через проксі в рантаймі; AspectJ — через зміну байт-коду
- Ключові терміни: Aspect (модуль), Pointcut (де), Advice (що), Join Point (конкретний метод)
- 5 типів Advice: @Before, @After, @AfterReturning, @AfterThrowing, @Around
- @Around — найпотужніший, але ОБОВ’ЯЗАНИЙ викликати pjp.proceed()
- Порядок аспектів визначається через @Order
- Spring AOP: тільки public методи Spring-бінів, self-invocation НЕ працює
- Оверхед AOP: ~1-5 мкс на виклик, у Highload сумується
Часті уточнюючі запитання:
- Чому Spring AOP не працює з private-методами? → Проксі перехоплює тільки виклики через proxy object, private-методи недоступні
- Коли обрати AspectJ замість Spring AOP? → Коли потрібні private-методи, поля, конструктори, або self-invocation
- @After vs @AfterReturning — в чому різниця? → @After = завжди (як finally), @AfterReturning = тільки при успішному завершенні
- Що таке ReflectiveMethodInvocation? → Pipeline Spring, послідовно проходить усі interceptors
Червоні прапорці (НЕ говорити):
- «Spring AOP працює з private-методами» — не працює
- «@Around без proceed() допустимий» — метод не викличеться взагалі
- «AOP додає мілісекунди overhead» — наносекунди (1-5 мкс)
- «Аспект зберігає стан у полях» — аспект = Singleton, не потокобезпечно
Пов’язані теми:
- [[13. Що таке proxy в Spring]]
- [[14. Коли Spring створює proxy]]
- [[16. Що таке аспект, advice, pointcut, join point]]
- [[17. Що робить анотація @Transactional]]