Aspectj切入点方法,在子类中带有注释

时间:2015-08-01 14:33:51

标签: java aspectj

我有2个班级

class Fragment1{
   createView(SomeObject p1, AnoterObject p2)
}

@AutoLayout(String annotationParam)
class Fragment2 extends Fragment1{
}

如何在Fragment2.createView上调用@Around createView并获取annotationParam?感谢

ADD: 如果我将方法存根添加到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);
    }

2 个答案:

答案 0 :(得分:2)

给出这个注释:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}

我们假设我们有三个类:

  • 没有注释的父类
  • 没有注释和
  • 的普通子类
  • 带注释的子类:
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 ""; }
}

这是一个小的驱动程序应用程序实例化所有三个类,调用它们上的所有可用方法,是否继承,具有不同的签名和返回类型:

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或其任何子类中的所有方法执行(因此+),但仅限于当前实例this承担@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()被调用三次,但只被拦截一次。您还可以从打印的getThis()对象中看到,实际上是截获了正确的执行。

答案 1 :(得分:1)

以下是示例

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