4

I have 2 classes

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

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

How i can do @Around createView on Fragment2.createView call and get annotationParam? Thanks

ADD: If i add method stub into Fragment2, it is start be possible to use next annotation @Around("createMethod(inflater, group, savedState) && @within(autoInflate)"), but it is a very ugly solution

SOLUTION: Thanks to @kriegaex i found solution:

@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 Answers2

3

Given this annotation:

package de.scrum_master.app;

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

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

Let us assume we have three classes:

  • a parent class without annotation,
  • a plain child class without annotation and
  • an annotated 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 ""; }
}

Here is a little driver application instantiating all three classes, calling all available methods on them, inherited or not, with different signatures and return types:

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);
    }
}

Finally, here is the aspect doing what was asked in the question: It intercepts all method executions in Parent or any of its subclasses (thus the +), but only if the class of the current instance this bears @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();
    }
}

The console log:

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

As you can see, doSomething() is called three times, but only intercepted once. You can also see from the printed getThis() object, that really the right execution is intercepted.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
1

Here is the example

public @interface customAnnotation {
    String value() default "someValue";
}


@Aspect
public class customAspect {

    @Around(value="@annotation(customAnnotation)")
    public Object customAdvice(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation ) throws Throwable {
    // ...
     }
}

See below as above snippet is inspired by these resources

Accessing Annotation-value in advice

Spring AOP: Getting parameters of the pointcut annotation

Community
  • 1
  • 1
M Sach
  • 33,416
  • 76
  • 221
  • 314
  • Unfortunately, your method does not work, because @annotation get annotations from nethod, not from class(( – Anatolii Kokuliuk Aug 01 '15 at 15:11
  • i did n't get you here. you can do whatever you want with parameter customAnnotation in your advice – M Sach Aug 01 '15 at 15:15
  • @ annotation command get annotation from method, but i mark with annatation class, not the method. for getting annotations from class i use @ within – Anatolii Kokuliuk Aug 01 '15 at 15:45
  • The original poster is right, this code intercepts annotated methods, not annotated classes. So the answer is wrong. – kriegaex Aug 02 '15 at 07:40
  • Thanks guys got it. Somhow i missed that orginal post has annotation on class instead of method. But still would keep the answer here so that if somebody comes here he can see both ways to intercept class and method with annotation. – M Sach Aug 02 '15 at 14:52