Reputation: 105213
My AspectJ aspect looks like this:
@Aspect
public class MyAspect {
private Child child;
public MyAspect() {
this.child = new Child();
}
@Around("... skipped ...")
public Object wrap(ProceedingJoinPoint point) throws Throwable {
// some custom functionality
return point.proceed();
}
}
This doesn't work because during the construction of Child
a wrap()
pointcut gets called and it leads to a runtime exception, since an instance of MyAspect
is not yet ready.
Is it possible to tell AspectJ somehow to call some method of MyAspect
right after its instantiating?
Upvotes: 1
Views: 3876
Reputation: 67457
New answer:
Here is a sample driver class Child
:
public class Child {
private String name;
public Child(String name) {
this.name = name;
System.out.println("Constructing child named " + this.name);
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public static void main(String[] args) {
Child myChild = new Child("Penélope");
System.out.println("My child is named " + myChild.getName());
myChild.setName("María Elena");
System.out.println("My child is now named " + myChild.getName());
}
}
And here is an aspect MyAspect
intercepting public method and constructor executions of Child
, but excluding the aspect constructor:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
private Child child;
public MyAspect() {
child = new Child("Scarlett");
System.out.println("Aspect child is named " + child.getName());
child.setName("Cristina");
System.out.println("Aspect child is now named " + child.getName());
}
@Around(
"(execution(public * Child.*(..)) || execution(public Child.new(..)))" +
"&& !cflow(initialization(MyAspect.new()))"
)
public Object wrap(ProceedingJoinPoint point) throws Throwable {
System.out.println(point.getStaticPart());
return point.proceed();
}
}
This is the sample output:
Constructing child named Scarlett
Aspect child is named Scarlett
Aspect child is now named Cristina
execution(void Child.main(String[]))
execution(Child(String))
Constructing child named Penélope
execution(String Child.getName())
My child is named Penélope
execution(void Child.setName(String))
execution(String Child.getName())
My child is now named María Elena
You can see that no Child
joinpoints are intercepted during aspect construction. BTW, otherwise you would get NoAspectBoundException
anyway. ;-)
Old answer:
You can combine your pointcut with something like (untested):
... && !cflow(MyAspect.new())
Ths should exclude what you do not want intercepted.
Upvotes: 3
Reputation: 28757
Perhaps you are best off trying to do the initialization inside of an advice. Eg-
after() : execution(MyAspect.new()) {
this.child = new Child();
}
But really, this strikes me as bad form. Having advice of the containing aspect being applied somewhere during the construction of Child
seems like a circular dependency. I'd try to refactor (perhaps into multiple aspects) in order to avoid the circularity.
Upvotes: 0