webprogr.ru Новости

RSS

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...


Последние новости

Применение AOP на практике

Применение 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() в репозитории, аспект регистрирует факт изменения.
Эта техника часто используется совместно с БД или журналом аудита.

Вывод:

Аспекты позволяют решать инфраструктурные задачи (логирование, транзакции, безопасность, аудит) централизованно.
Это повышает читаемость и уменьшает количество повторяющегося кода.
Основная логика классов остается «чистой» — они выполняют только свои бизнес-функции,
а вся вспомогательная обработка выполняется в аспектах.
Рейтинг@Mail.ru