Это была интересная проблема, поэтому я создал небольшой пример приложения для решения этой проблемы! (И улучшил его с помощью обратной связи Синухе.)
Я создал 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
.
Второй pointcut добавит точку соединения, когда будут выполнены следующие условия:
- публичный метод
- first
*
- подстановочный знак для каждого типа возвращаемого значения.
- second
*
- шаблон для всех методов всех классов.
(..,
соответствует нулю многим параметрам любого типа перед аннотированным параметром.
@aspects.MyParamAnnotation (*),
соответствует параметру, аннотированному данной аннотацией.
..)
соответствует нулю многим параметрам любого типа после аннотированного параметра.
Наконец, совет @Before
рекомендует все методы, при которых все условия в обеих точках выполняются.
Pointcut работает как с AspectJ, так и с Spring AOP!
Когда дело касается производительности. Накладные расходы невелики, особенно с AspectJ, который выполняет переплетение во время компиляции или загрузки.