Рубрики
Без рубрики

Введение в выражения Pointcut весной

Быстрое и практическое введение в весенние выражения AOP и Pointcut.

Автор оригинала: baeldung.

1. Обзор

В этом учебнике мы обсудим язык выражения Spring AOP pointcut.

Сначала мы введем некоторую терминологию, используемую в аспектно-ориентированном программировании. присоединиться к точке является шагом выполнения программы, например, выполнение метода или обработка исключения. Весной AOP точка присоединения всегда представляет собой выполнение метода. pointcut является предикатом, который соответствует точкам присоединения и язык выражения pointcut это способ описания pointcuts программным путем.

2. Использование

Выражение pointcut может отображаться как значение @Pointcut аннотация:

@Pointcut("within(@org.springframework.stereotype.Repository *)")
public void repositoryClassMethods() {}

Декларация метода называется pointcut подпись . Он предоставляет имя, которое может быть использовано советом аннотации для обозначения этого pointcut.

@Around("repositoryClassMethods()")
public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
    ...
}

Выражение pointcut также может отображаться как значение выражение имущество aop:pointcut ярлык:


    

3. Конструкторы Pointcut

Выражение pointcut начинается с pointcut , который является ключевым словом говорю Весна АОП, что соответствовать. Существует несколько точечных проектаторов, таких как выполнение метода, типа, аргументов метода или аннотаций.

3.1 исполнение

Основной весенний PCD исполнение , который соответствует методу выполнения присоединиться точек.

@Pointcut("execution(public String com.baeldung.pointcutadvice.dao.FooDao.findById(Long))")

Этот пример pointcut будет точно соответствовать исполнению findById метод ФуДао класс. Это работает, но это не очень гибкий. Предположим, мы хотели бы сопоставить все методы ФуДао класс, который может иметь различные подписи, типы возврата и аргументы. Для достижения этой цели мы можем использовать подстановочные знаки:

@Pointcut("execution(* com.baeldung.pointcutadvice.dao.FooDao.*(..))")

Здесь первый подстановочный знак соответствует любому значению возврата, второй соответствует названию любого метода, а (..) шаблон соответствует любому количеству параметров (ноль или более).

3.2 в пределах

Еще один способ достичь того же результата из предыдущего раздела с помощью в PCD, который ограничивает соответствие для присоединения точек определенных типов.

@Pointcut("within(com.baeldung.pointcutadvice.dao.FooDao)")

Мы также можем соответствовать любому типу в com.baeldung пакет или подпакет.

@Pointcut("within(com.baeldung..*)")

3.3 это и цель

этот ограничения соответствия для присоединения точек, где ссылка на фасоль является экземпляром данного типа, в то время как целевые ограничения соответствия точкам присоединения, где целевой объект является экземпляром данного типа. Первый работает, когда Spring AOP создает прокси на основе CGLIB, а второй используется при создании прокси на основе JDK. Предположим, что целевой класс реализует интерфейс:

public class FooDao implements BarDao {
    ...
}

В этом случае Spring AOP будет использовать прокси на основе JDK, и вы должны использовать целевые PCD, потому что прокси-объект будет экземпляром Прокси- класса и реализации Бардао интерфейс:

@Pointcut("target(com.baeldung.pointcutadvice.dao.BarDao)")

С другой стороны, если ФуДао не реализует ни интерфейс, ни проксиTargetClass свойство установлено, чтобы верно, то прокси-объект будет подкласс ФуДао и этот PCD может быть использован:

@Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")

3,4 арга

Этот PCD используется для сопоставления конкретных аргументов метода:

@Pointcut("execution(* *..find*(Long))")

Этот pointcut соответствует любому методу, который начинается с поиском и имеет только один параметр типа Длинные . Если мы хотим сопоставить метод с любым количеством параметров, но с параметром кулака типа Длинные , мы могли бы использовать следующее выражение:

@Pointcut("execution(* *..find*(Long,..))")

3,5 @target

@target PCD (не следует путать с целевой PCD описано выше) ограничения соответствия для присоединения точек, где класс объекта выполнения имеет аннотацию данного типа:

@Pointcut("@target(org.springframework.stereotype.Repository)")

3,6 @args

Этот PCD ограничивает соответствие точкам присоединения, где тип времени выполнения фактических пройденных аргументов имеет аннотации данного типа (ы). Предположим, что мы хотим проследить все методы принятия бобов, аннотированных @Entity аннотация:

@Pointcut("@args(com.baeldung.pointcutadvice.annotations.Entity)")
public void methodsAcceptingEntities() {}

Чтобы получить доступ к аргументу, мы должны предоставить Присоединиться к аргумент к совету:

@Before("methodsAcceptingEntities()")
public void logMethodAcceptionEntityAnnotatedBean(JoinPoint jp) {
    logger.info("Accepting beans with @Entity annotation: " + jp.getArgs()[0]);
}

3,7 @within

Этот PCD ограничивает соответствие для присоединения точек в типах, которые имеют данное аннотацию:

@Pointcut("@within(org.springframework.stereotype.Repository)")

Что эквивалентно:

@Pointcut("within(@org.springframework.stereotype.Repository *)")

3,8 @annotation

Этот PCD ограничивает соответствие точкам присоединения, где объект точки присоединения имеет данное аннотацию. Например, мы можем создать @Loggable аннотация:

@Pointcut("@annotation(com.baeldung.pointcutadvice.annotations.Loggable)")
public void loggableMethods() {}

Затем мы можем войти в журнал выполнения методов, отмеченных этой аннотации:

@Before("loggableMethods()")
public void logMethod(JoinPoint jp) {
    String methodName = jp.getSignature().getName();
    logger.info("Executing method: " + methodName);
}

4. Объединение выражений Pointcut

Выражения Pointcut можно комбинировать с помощью && , и !

@Pointcut("@target(org.springframework.stereotype.Repository)")
public void repositoryMethods() {}

@Pointcut("execution(* *..create*(Long,..))")
public void firstLongParamMethods() {}

@Pointcut("repositoryMethods() && firstLongParamMethods()")
public void entityCreationMethods() {}

5. Заключение

В этом быстром интро к весне AOP и pointcuts, мы проиллюстрировали некоторые примеры использования выражений pointcut.

Полный набор примеров можно найти более на GitHub .