Spring AOP Исключить некоторые классы

Я использую Spring AspectJ для статистики выполнения методов ведения журнала, однако я хочу исключить из него некоторые классы и методы без изменения выражения pointcut.

Чтобы исключить определенные методы, я создал пользовательскую аннотацию, которую я использую для фильтрации. Однако я не могу сделать то же самое с классами.

Вот мое определение аспекта -

@Around("execution(* com.foo.bar.web.controller.*.*(..)) "
            + "&& [email protected](com.foo.bar.util.NoLogging)")
public Object log(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    // logging logic here
}

NoLogging - это моя аннотация для исключения методов.

Итак, как я могу отфильтровать определенные классы без изменения выражения pointcut и без добавления новых советников?

Ответ 1

Итак, я нашел решение - используйте @target PCD (указатели pointcut), чтобы отфильтровать классы с определенной аннотацией. В этом случае у меня уже есть аннотация @NoLogging, поэтому я могу это использовать. Обновленное выражение pointcut станет следующим:

@Around("execution(* com.foo.bar.web.controller.*.*(..)) "
            + "&& [email protected](com.foo.bar.util.NoLogging)" 
            + "&& [email protected](com.foo.bar.util.NoLogging)")
public Object log(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    // logging logic here
}

Объяснение -

execution(* com.foo.bar.web.controller.*.*(..)) - все методы всех классов в пакете c.f.b.w.controller

"&& [email protected](com.foo.bar.util.NoLogging)" - которые не имеют аннотации @NoLogging для них

"&& [email protected](com.foo.bar.util.NoLogging)" - и в классе которого также нет аннотации @NoLogging.

Итак, теперь мне просто нужно добавить аннотацию @NoLogging к любому классу, методы которого я хочу исключить из аспект.

Более PCD можно найти в документации Spring AOP - http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-pointcuts-designators

Ответ 2

По Spring Документация AOP

PCD может быть & ed, || 'ed, и! (отрицается).

Итак, я думаю, что это больше из проб и ошибок. Я думаю, вы можете попробовать что-то вроде && [email protected] @within применимо для типов. Или вы можете попробовать [email protected]

Но опять же я думаю, что это может быть сложно.

Другой подход: объявить два определения pointcut и объединить их. И пример, здесь, на странице документации. Я бы попробовал это первым. Что-то вроде

@Pointcut(executionPC() && nonAnnotatedClassesPC() && nonAnnotatedMethodsPC())

Отказ от ответственности: как я уже сказал, это больше похоже на проб и ошибок. И у меня нет четкого рабочего примера.