Ответ 1
Это была интересная проблема, поэтому я создал небольшое примерное приложение для решения дела! (И улучшил его с обратной связью Sinuhe.)
Я создал класс 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, который выполняет переплетение во время компиляции или времени загрузки.