Reputation: 183
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);
}
Upvotes: 5
Views: 4847
Reputation: 67317
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:
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.
Upvotes: 4
Reputation: 34424
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
Upvotes: 1