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}}

перейти...


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

Pointcut — выбор точек применения аспекта

Pointcut — выбор точек применения аспекта

    Pointcut (срез) — это выражение, определяющее, где именно в коде должен сработать аспект.

    В Spring AOP чаще всего используется выражение execution(), которое описывает методы, на которые будет действовать совет (advice).

    Примеры:
    • execution(* com.example.service.*.*(..)) — все методы в пакете service.
    • execution(public * save*(..)) — все публичные методы, начинающиеся с save.
    • execution(* *(..)) — любой метод (всех классов и пакетов).

Подробное объяснение

В AOP «точкой соединения» (join point) называют место в программе, где можно вставить дополнительное действие.
Например — вызов метода, выбрасывание исключения или доступ к переменной.

Pointcut определяет набор таких точек, к которым будет применен аспект.
Без него Spring не знает, где именно выполнять ваш код из @Before, @After и других советов.

Самый распространенный способ описать pointcut — использовать выражение execution().
1. Синтаксис выражения execution()

Общий формат:

execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)

Разберем на примере:

execution(public * com.example.service.UserService.getUserById(..))

Расшифровка:

    public — модификатор доступа;

    * — любой возвращаемый тип;

    com.example.service.UserService — класс, методы которого интересуют;

    getUserById — имя метода;

    ( .. ) — любое количество любых параметров.

Таким образом, этот pointcut «перехватит» вызовы всех публичных методов getUserById в UserService.
2. Использование шаблонов (* и ..)
Шаблон Значение
* Любое имя или тип (например, метод любого имени, возвращаемый тип любой).
.. Любое количество параметров любого типа.
*.*(..) Все методы всех классов текущего пакета.

Примеры:

@Before("execution(* com.myapp.repository.*.*(..))")
public void beforeRepository() {
    System.out.println("Вызов метода репозитория");
}

@After("execution(* save*(..))")
public void afterSaveMethods() {
    System.out.println("Метод с префиксом save завершился");
}

Первый аспект отработает перед любым методом в пакете repository,
второй — после любых методов, начинающихся со слова save.
3. Объединение выражений

Можно комбинировать pointcut-условия с помощью логических операторов:

    && — И

    || — ИЛИ

    ! — НЕ

Пример:

@Before("execution(* com.example.service.*.*(..)) && !execution(* *.toString(..))")
public void logAllExceptToString() {
    System.out.println("Метод сервиса (кроме toString) вызван");
}

Здесь аспект применяется ко всем методам в сервисах, кроме toString().
4. Вынос pointcut в отдельный метод

Чтобы не дублировать выражения, их можно вынести в отдельный метод и ссылаться по имени.

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void allServiceMethods() {}

    @Before("allServiceMethods()")
    public void beforeCall() {
        System.out.println("Вызов метода сервиса");
    }
}

Метод allServiceMethods() здесь пуст, он просто служит меткой для повторного использования выражения.
Это улучшает читаемость и позволяет применять один и тот же pointcut в нескольких советах.

Вывод:
Pointcut — механизм точного выбора мест, где должен сработать аспект.
С помощью выражений execution() можно настроить уровень детализации — от отдельных методов до целых пакетов.
Такой подход делает систему гибкой: аспекты применяются ровно там, где нужно, без вмешательства в исходный код.
Рейтинг@Mail.ru