Методы сопоставления Pointcut с аннотируемыми параметрами

Я должен создать аспект с pointcut соответствие методу если:

  • Общедоступно
  • Его класс аннотируется @Controller (Наконец не делает),
  • Один из его параметров (может иметь многих) аннотируется @MyParamAnnotation.

Я думаю, что первые два условия легки, но я не знаю если его возможное выполнять третье с Spring. Если это не, возможно, я могу изменить его в:

  • Один из его параметров является экземпляром типа com.me. MyType (или реализации некоторый интерфейс)

Вы думаете, что возможно достигнуть этого? И производительность будет хороша?

Спасибо

Править: Один пример метода сопоставления. Как Вы видите, MyMethod не аннотируется (но это может быть).

@Controller
public class MyClass {
    public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) {
        ...
    }
}

Править: Решение я наконец использовал, на основе ответов @Espen. Как Вы видите, я изменил свои условия немного: класс не должен на самом деле быть @Controller.

@Around("execution(public * * (.., @SessionInject (*), ..))")
public void methodAround(JoinPoint joinPoint) throws Exception {
    ...
}
17
задан Espen 31 May 2010 в 19:49
поделиться

1 ответ

Это была интересная проблема, поэтому я создал небольшой пример приложения для ее решения! (И улучшил его с помощью отзывов Синухе.)

Я создал класс DemoController, который должен работать как пример для аспекта:

@Controller
public class DemoController {

    public void soSomething(String s, @MyParamAnnotation Double d, Integer i) {
    }

    public void doSomething(String s, long l, @MyParamAnnotation int i) {
    }

    public void doSomething(@MyParamAnnotation String s) {
    }

    public void doSomething(long l) {
    }
}

Аспект, который добавит точку соединения на первые три метода, но не на последний метод, где параметр не аннотирован @MyParamAnnotation:

@Aspect
public class ParameterAspect {

    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void beanAnnotatedWithAtController() {
    }

    @Pointcut("execution(public * *(.., @aspects.MyParamAnnotation (*), ..))")
    public void methodWithAnnotationOnAtLeastOneParameter() {
    }

    @Before("beanAnnotatedWithAtController() " 
            + "&& methodWithAnnotationOnAtLeastOneParameter()")
    public void beforeMethod() {    
        System.out.println("At least one of the parameters are " 
                  + "annotated with @MyParamAnnotation");
    }
}

Первый pointcut создаст точку соединения на все методы внутри классов, помеченных @Controller.

Второй пункт добавит точку соединения при выполнении следующих условий:

  • public method
  • first * - подстановочный знак для каждого возвращаемого типа.
  • second * - подстановочный знак для всех методов во всех классах.
  • (..., соответствует от нуля до многих параметров любого типа перед аннотированным параметром.
  • @aspects.MyParamAnnotation (*), соответствует параметру, аннотированному данной аннотацией.
  • ...) соответствует от нуля до многих параметров любого типа после аннотированного параметра.

Наконец, совет @Before советует все методы, в которых выполнены все условия в обоих указателях.

Этот совет работает как с AspectJ, так и с Spring AOP!

Что касается производительности. Накладные расходы невелики, особенно с AspectJ, который выполняет плетение во время компиляции или во время загрузки.

22
ответ дан 30 November 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: