带注释的方法或带注释的类中的方法的切入点 [英] Pointcut for annotated methods or methods in annotated classes
问题描述
我需要一个用@X 注释的类中的方法或用@X 注释的方法的切入点.我还需要注释对象.如果类和方法都被注释我更喜欢将方法注释作为参数.
I need a pointcut for methods in classes annotated with @X or methods annotated with @X. I also need the annotation object. If both the class and the method are annotated I prefer to get the method annotation as argument.
我尝试了以下操作,这会产生不一致的绑定"警告.(为什么不直接将它们设置为 null?)
I tried the following, which creates an "inconsistent binding" warning. (Why not just set them null?)
@Around("@annotation(methodLevelX) || @within(classLevelX)")
public Object advise(ProceedingJoinPoint pjp, X methodLevelX, X classLevelX)
以下创建了一个参数 x 跨'||'的模糊绑定在切入点"警告.(这在我看来不一定有意义:为什么不绑定第一个短路评估?)
The following creates a "ambiguous binding of parameter(s) x across '||' in pointcut" warning. (Which does not necessarily make sense in my opinion: Why not bind the first short circuited evaluation?)
@Around("@annotation(x) || @within(x)")
public Object advise(ProceedingJoinPoint pjp, X x)
如果存在类和方法注释,则将之前的尝试一分为二自然会导致两个方法调用.
Splitting the previous attempt in two naturally results in two method calls if class and method annotations are present.
我知道我可以通过反射和我想要的注释来获取方法和类,像这样的切入点:
I know I could just get the method and class with reflection and my desired annotation with a pointcut like this:
@Around("@annotation(com.package.X) || @within(com.package.X)")
但我不想这样做.
有没有什么一个切入点,一个方法,一个注解参数"的解决方案,我的需求不需要反射?
推荐答案
不完全,但差不多.您将需要两个切入点、两个通知,但您可以将工作委托给一个方法.下面是它的样子:
Not quite, but almost. You will need two pointcuts, two advices, but you can delegate the work to a single method. Here's how it would look like:
@Aspect
public class AnyAspectName {
@Pointcut("execution(@X * *.*(..))")
void annotatedMethod() {}
@Pointcut("execution(* (@X *).*(..))")
void methodOfAnnotatedClass() {}
@Around("annotatedMethod() && @annotation(methodLevelX)")
public Object adviseAnnotatedMethods(ProceedingJoinPoint pjp, X methodLevelX)
throws Throwable {
return aroundImplementation(pjp, methodLevelX);
}
@Around("methodOfAnnotatedClass() && !annotatedMethod() && @within(classLevelX)")
public Object adviseMethodsOfAnnotatedClass(ProceedingJoinPoint pjp, X classLevelX)
throws Throwable {
return aroundImplementation(pjp, classLevelX);
}
public Object aroundImplementation(ProceedingJoinPoint pjp, X annotation)
throws Throwable {
return pjp.proceed();
}
}
请注意,除了将 @annotation()
和 @within()
切入点分开之外,我还对结果切入点添加了限制,使它们不会太宽泛.我想你想要方法执行连接点,所以我添加了需要的切入点表达式,将它限制为方法执行.他们是匹配的
Note that besides splitting apart the @annotation()
and @within()
pointcuts, I added restrictions to the resulting pointcuts so that they aren't too broad. I suppose you want method execution join points, so I added the needed pointcut expressions that would restrict it to method execution. They are matching
- 执行任何用
@X
注释的方法,在任何包中的任何类中的任何返回类型用于第一个建议 - 在第二个用
@X
注释的任何类中执行具有任何返回类型的任何方法.
- execution of any method annotated with
@X
with any return type in any class being in any package for the first advice - execution of any method with any return type in any class annotated with
@X
for the second.
进一步限制 @within(X)
和 @annotation(X)
就派上用场了,因为 @within(X)
本身会匹配
Further restricting @within(X)
and @annotation(X)
comes in handy, because @within(X)
by itself would match
在类型中定义关联代码的任何连接点X
any join point where the associated code is defined in a type with an annotation of type
X
包括method-execution、method-call、constructor-execution、constructor-call、预初始化、静态初始化、初始化、字段设置、字段获取、exception-handler,lock 类型的连接点(尽管并非所有连接点都对 around 建议有效).类似地,@annotation(X)
本身意味着
which would include method-execution, method-call, constructor-execution, constructor-call, pre-initialization, static initialization, initialization, field set, field get, exception-handler, lock type join points (not all join points are valid for around advices though). Similarly, @annotation(X)
by itself would mean
主题具有 X
这也可能意味着前面提到的大部分连接点,具体取决于注释的目标类型.
which could also mean most of the previously mentioned join points, depending on the target type of your annotation.
这篇关于带注释的方法或带注释的类中的方法的切入点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!