Применение AOP на практике
Аспектно-ориентированное программирование в Spring чаще всего используется для решения повторяющихся задач,
не связанных напрямую с бизнес-логикой.
Типичные сценарии применения AOP:
• Логирование действий и ошибок
• Измерение времени выполнения методов
• Управление транзакциями
• Проверка безопасности (авторизация)
• Аудит изменений данных
Эти аспекты позволяют разгрузить код сервисов и сделать архитектуру чище и удобнее для сопровождения.
Подробное объяснение
В каждом проекте существуют действия, которые должны выполняться во многих местах, но не являются частью основной бизнес-логики.
Если такие операции писать вручную в каждом методе, код быстро превращается в дублирующийся и трудночитаемый.
AOP позволяет вынести все это в отдельные компоненты (аспекты) и подключать их централизованно.
1. Логирование действий и ошибок
Один из самых распространенных сценариев AOP — ведение логов.
Без AOP:
public void createOrder(Order order) {
logger.info("Создание заказа " + order);
repository.save(order);
logger.info("Заказ сохранен успешно");
}
С AOP:
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.shop.service.*.*(..))")
public void beforeCall(JoinPoint jp) {
System.out.println("Вызов метода: " + jp.getSignature());
}
@AfterThrowing(pointcut = "execution(* com.shop.service.*.*(..))", throwing = "ex")
public void afterError(Exception ex) {
System.out.println("Ошибка: " + ex.getMessage());
}
}
Теперь каждый метод сервиса автоматически логируется — без необходимости вставлять logger.info() вручную.
2. Измерение времени выполнения
AOP можно использовать, чтобы оценить производительность кода.
Это помогает находить «узкие места» и оптимизировать работу приложения.
@Aspect
@Component
public class PerformanceAspect {
@Around("execution(* com.shop.service.*.*(..))")
public Object measureTime(ProceedingJoinPoint jp) throws Throwable {
long start = System.currentTimeMillis();
Object result = jp.proceed();
long duration = System.currentTimeMillis() - start;
System.out.println(jp.getSignature() + " занял " + duration + " мс");
return result;
}
}
Такой аспект будет автоматически выводить, сколько времени занял каждый вызов метода в сервисах.
3. Управление транзакциями
В Spring поддержка транзакций реализована именно с помощью AOP.
Когда вы добавляете аннотацию @Transactional, Spring создает вокруг метода прокси,
который открывает и закрывает транзакцию автоматически:
@Transactional
public void saveOrder(Order order) {
orderRepository.save(order);
paymentService.processPayment(order);
}
Spring сам выполняет:
открытие транзакции перед методом,
фиксацию (commit) при успешном завершении,
откат (rollback) при ошибке.
Разработчику не нужно вызывать методы транзакционного менеджера вручную — все это обеспечивается аспектом.
4. Проверка безопасности (авторизация)
Безопасность — еще один пример аспектно реализованной функциональности.
Spring Security добавляет фильтры и аспекты, которые проверяют права пользователя до выполнения метода.
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
Аннотация @PreAuthorize — это тоже AOP-аспект, который перехватывает вызов метода
и проверяет, есть ли у текущего пользователя нужная роль.
Если нет — выполнение метода блокируется.
5. Аудит и отслеживание изменений
AOP удобно применять для аудита — записи информации о том, кто и когда изменил данные.
@Aspect
@Component
public class AuditAspect {
@AfterReturning("execution(* com.shop.repository.*.save(..))")
public void afterSave(JoinPoint jp) {
System.out.println("Аудит: объект сохранен — " + jp.getArgs()[0]);
}
}
Каждый раз, когда вызывается save() в репозитории, аспект регистрирует факт изменения.
Эта техника часто используется совместно с БД или журналом аудита.
Вывод:
Аспекты позволяют решать инфраструктурные задачи (логирование, транзакции, безопасность, аудит) централизованно.
Это повышает читаемость и уменьшает количество повторяющегося кода.
Основная логика классов остается «чистой» — они выполняют только свои бизнес-функции,
а вся вспомогательная обработка выполняется в аспектах.
