子类中带有注释的Aspectj切入点方法
Aspectj pointcut method with annotation in subclass
我有2个类
class Fragment1{
createView(SomeObject p1, AnoterObject p2)
}
@AutoLayout(String annotationParam)
class Fragment2 extends Fragment1{
}
如何在 Fragment2.createView 调用上执行 @Around createView 并获取 annotationParam?谢谢
添加:
如果我将方法存根添加到 Fragment2 中,则可以开始使用下一个注释
@Around("createMethod(inflater, group, savedState) && @within(autoInflate)")
,但这是一个非常丑陋的解决方案
解决方案:
感谢@kriegaex 我找到了解决方案:
@Around("execution(* com.github.a_kokulyuk.kotakt.ui.BaseFragment+.*(*, *, *)) && args(inflater, parent, savedState) && @this(an)")
public Object doLayout(ProceedingJoinPoint jo, LayoutInflater inflater, ViewGroup parent, Bundle savedState, AutoLayout an) throws Throwable {
return inflater.inflate(an.value(), parent, false);
}
这是例子
public @interface customAnnotation {
String value() default "someValue";
}
@Aspect
public class customAspect {
@Around(value="@annotation(customAnnotation)")
public Object customAdvice(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation ) throws Throwable {
// ...
}
}
请参阅下文,上面的代码段灵感来自这些资源
Accessing Annotation-value in advice
Spring AOP: Getting parameters of the pointcut annotation
鉴于此注释:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
让我们假设我们有三个 classes:
- a parent class 无注释,
- 没有注释的普通childclass和
- 一个注释 child class:
package de.scrum_master.app;
public class Parent {
public void doSomething() {}
}
package de.scrum_master.app;
public class PlainChild extends Parent {
int doSomethingElse() { return 11; }
}
package de.scrum_master.app;
@MyAnnotation
public class AnnotatedChild extends Parent {
String doSomethingSpecial(int number) { return ""; }
}
这是一个小驱动程序应用程序,它实例化了所有三个 classes,调用它们的所有可用方法,继承与否,具有不同的签名和 return 类型:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Parent().doSomething();
new PlainChild().doSomething();
new PlainChild().doSomethingElse();
new AnnotatedChild().doSomething();
new AnnotatedChild().doSomethingSpecial(123);
}
}
最后,这是做问题中所问的方面:它拦截 Parent
或其任何子 class 中的所有方法执行(因此 +
) , 但前提是当前实例 this
的 class 包含 @MyAnnotation
:
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@Around(
"execution(* de.scrum_master.app.Parent+.*(..)) && " +
"@this(de.scrum_master.app.MyAnnotation)"
)
public Object myAdvice(ProceedingJoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
System.out.println(" " + thisJoinPoint.getThis());
return thisJoinPoint.proceed();
}
}
控制台日志:
execution(void de.scrum_master.app.Parent.doSomething())
de.scrum_master.app.AnnotatedChild@681a9515
execution(String de.scrum_master.app.AnnotatedChild.doSomethingSpecial(int))
de.scrum_master.app.AnnotatedChild@13221655
可以看到,doSomething()
被调用了3次,只被拦截了一次。从打印出来的getThis()
object也可以看出,确实是正确的执行被拦截了
我有2个类
class Fragment1{
createView(SomeObject p1, AnoterObject p2)
}
@AutoLayout(String annotationParam)
class Fragment2 extends Fragment1{
}
如何在 Fragment2.createView 调用上执行 @Around createView 并获取 annotationParam?谢谢
添加:
如果我将方法存根添加到 Fragment2 中,则可以开始使用下一个注释
@Around("createMethod(inflater, group, savedState) && @within(autoInflate)")
,但这是一个非常丑陋的解决方案
解决方案: 感谢@kriegaex 我找到了解决方案:
@Around("execution(* com.github.a_kokulyuk.kotakt.ui.BaseFragment+.*(*, *, *)) && args(inflater, parent, savedState) && @this(an)")
public Object doLayout(ProceedingJoinPoint jo, LayoutInflater inflater, ViewGroup parent, Bundle savedState, AutoLayout an) throws Throwable {
return inflater.inflate(an.value(), parent, false);
}
这是例子
public @interface customAnnotation {
String value() default "someValue";
}
@Aspect
public class customAspect {
@Around(value="@annotation(customAnnotation)")
public Object customAdvice(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation ) throws Throwable {
// ...
}
}
请参阅下文,上面的代码段灵感来自这些资源
Accessing Annotation-value in advice
Spring AOP: Getting parameters of the pointcut annotation
鉴于此注释:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
让我们假设我们有三个 classes:
- a parent class 无注释,
- 没有注释的普通childclass和
- 一个注释 child class:
package de.scrum_master.app;
public class Parent {
public void doSomething() {}
}
package de.scrum_master.app;
public class PlainChild extends Parent {
int doSomethingElse() { return 11; }
}
package de.scrum_master.app;
@MyAnnotation
public class AnnotatedChild extends Parent {
String doSomethingSpecial(int number) { return ""; }
}
这是一个小驱动程序应用程序,它实例化了所有三个 classes,调用它们的所有可用方法,继承与否,具有不同的签名和 return 类型:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Parent().doSomething();
new PlainChild().doSomething();
new PlainChild().doSomethingElse();
new AnnotatedChild().doSomething();
new AnnotatedChild().doSomethingSpecial(123);
}
}
最后,这是做问题中所问的方面:它拦截 Parent
或其任何子 class 中的所有方法执行(因此 +
) , 但前提是当前实例 this
的 class 包含 @MyAnnotation
:
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@Around(
"execution(* de.scrum_master.app.Parent+.*(..)) && " +
"@this(de.scrum_master.app.MyAnnotation)"
)
public Object myAdvice(ProceedingJoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
System.out.println(" " + thisJoinPoint.getThis());
return thisJoinPoint.proceed();
}
}
控制台日志:
execution(void de.scrum_master.app.Parent.doSomething())
de.scrum_master.app.AnnotatedChild@681a9515
execution(String de.scrum_master.app.AnnotatedChild.doSomethingSpecial(int))
de.scrum_master.app.AnnotatedChild@13221655
可以看到,doSomething()
被调用了3次,只被拦截了一次。从打印出来的getThis()
object也可以看出,确实是正确的执行被拦截了