Crosscut concerns in middle of methods
-
29-09-2019 - |
Question
it's convenient for AOP (e.g. AspectJ, SpringAOP) to deal with(advise on) crosscut concerns at pointcuts around methods below,
"Sandwich" code
methodA {
crosscut code
user code A
crosscut code
}
methodB {
crosscut code
user code B
crosscut code
}
Is AOP apt to crosscut concerns overlapped to user code below? How?
"Spaghetti" code
methodX {
user code x1
crosscut code
user code x2
crosscut code
}
methodY {
user code y1
crosscut code
user code y2
crosscut code
}
Thanks!
Solution
Spring AOP won't help, as it only understands the execution() pointcut.
AspectJ includes a lot more pointcuts, including the withincode() construct, which sounds like what you want:
withincode(* YourClass.methodX(. .))
this lets you advise all join points inside a given method exection
Read AspectJ in Action for more info, it's a very good book about both AspectJ and Spring AOP.
EDIT:
here is some sample code:
package com.dummy.aspectj;
import java.util.Arrays;
import java.util.Collections;
public class DummyClass{
public static void main(final String[] args){
System.out.println(Arrays.asList("One", Collections.singleton("Two")));
System.out.println("Enough?");
}
}
package com.dummy.aspectj;
import java.util.Arrays;
public aspect DummyAspect{
pointcut callWithinMain() :
withincode(* com.dummy.aspectj.DummyClass.main(..)) // anything inside DummyClass.main
&& call(* *.*(..)); // but only method calls
before() : callWithinMain() {
System.out.println("\n***************************************************");
System.out.println("** Calling:\n**\t"
+ thisJoinPointStaticPart.getSignature()
+ "\n** with arguments:\n**\t "
+ Arrays.deepToString(thisJoinPoint.getArgs()) );
System.out.println("***************************************************\n");
}
}
running the DummyClass from Eclipse / AJDT generates this output:
***************************************************
** Calling:
** Set java.util.Collections.singleton(Object)
** with arguments:
** [Two]
***************************************************
***************************************************
** Calling:
** List java.util.Arrays.asList(Object[])
** with arguments:
** [[One, [Two]]]
***************************************************
***************************************************
** Calling:
** void java.io.PrintStream.println(Object)
** with arguments:
** [[One, [Two]]]
***************************************************
[One, [Two]]
***************************************************
** Calling:
** void java.io.PrintStream.println(String)
** with arguments:
** [Enough?]
***************************************************
Enough?
OTHER TIPS
While some AOP implementations might allow you to do this, this could be indicative of need to refactor those methods into more composed methods as they might be doing too much if one has the need to crosscut concerns into the middle of the methods. Doing so would give you this:
methodX
{
usercodemethod1();
usercodemethod2();
}
usercodemethod1
{
user code x1
crosscut code
}
usercodemethod2
{
user code x2
crosscut code
}