in Spring

Spring AOP tutorial

In this tutorial I will go through all important spring AOP details that will enable you to use AOP with ease.

  • How to enable AOP in java
  • How to create Aspect
  • How to create Point cut with designators
    • args()
    • @args()
    • execution()
    • target()
    • @target()
    • within()
    • @within
    • @annotation
  • How to use advices ( Before, After, AfterThrowing ,After returning) with especial attention on how to pass parameters to your aspect methods
  • How to use Around advice

Classes, interfaces and annotations Used in this tutorial

I will use only few classes in this tutorial, first is the Knight interface and its implementation MajesticKnight, observe two annotations @Primary and @MethodAnnotation. Next we have KnightWeapon that is annotated with @ArgAnnotation. This annotations will come to be important when in next code examples.

How to enable spring AOP

Enabling spring AOP in java is done using  @EnableAspectJAutoProxy, lets observe configuration class KingConfig that creates two beans, one is MajesticKnight and other is KnightOneMethodAspect.

If you are using component scan in your configuration you can use @ComponentScan and not create beans manually.

How to create spring aspect

Here is one example of aspect , notice the annotation @Aspect (org.aspectj.lang.annotation.Aspect) this will marks this class as aspect. We also have one empty method getKnightName that is annotated with @Pointcut, every aspect must have pointcut definition to explain what join points should be woven. In this case method getKnightName of bean Knight is woven.

At last we have method that is executed before getKnightName is called, it is annotated with  @Before("getKnightName()") advice @Before tells when method is to be executed and value of annotations tell what point cut is relates to.

Advices

Spring offers few advices that we can use

  • Before
  • After
  • AfterThrowing
  • AfterReturning
  • Around

Lets expand the KnightOneMethod aspect a bit to show how to use all of this advices.

Order in which annotated methods are executed in this aspect is:

  1. @Before
  2. @After
  3. @AfterReturning or @AfterThrowing , this depends if your method returns anything or throws exception

Lets observe two interesting advices AfterReturning and AfterThrowing, here it is important to notice that methods receive the returned value and thrown exception.

@Around advice

Above advices can be replaced with one advice named @Around, here is changed code that demonstrates this advice.

It is important to notice that joinPoint of class ProceedingJoinPoint has a method proceed() that must be called in order to spring to actually call method in this case getKnightName.

ProceedingJoinPoint class is very interesting here are few methods that you may find interesting

  • Object getTarget();  Returns the target object.

  • Object[] getArgs();  Returns the arguments at this join point

  • Signature getSignature();  Returns the signature at the join point

  • String getKind();  Returns a String representing the kind of join point

Designator args()

Designators are used to filter all join points that match some specific criteria. Args and used to filter all join points that have certain  parameter types. If you check the Knight interface and its methods it has two methods with String type parameter.

StringBefore method does not accept any parameters, lets see how to change that.

It is important to notice that test is the parameter name, in this example it is named test. In case your desired join point has multiple parameters adding .. will take this into account.

Designator @args

Designator @args works in a similar way as args with just one difference, it selects join points that have parameters that are annotated with desired annotation.

This is the Knight method we want to select  void setKnightWeapon(KnightWeapon knightWeapon); , KnightWeapon class is annotated with @ArgAnnotation(value = 99) .

Lets try to spice this up a bit and mix it with args designator.

We have method pointcut that selects all methods in Knight bean that have KnightWeapon as argument, before we have learned how to pass pass argument in our advice. Now observe string pointcut we have combined designators and added  @args(rs.pscode.model.ArgAnnotation)

Problem is clearly visible, we sometimes want to have annotation as parameter to the advice method. Here is an example that will show you how to do this.

Do you see the similarity between args and @args when you want to pass a method argument? Here is once more so that is clearly visible, this is very important as it works the same way on other designators we are going to cover in this tutorial.

 

Designator @annotation

When you want to select join points that are annotated with annotation of your choice you can use @annotation. MajesticKnight has one method that is annotated with MethodAnnotation, lets create one aspect that will add Before advice.

Designator target

To target join points of given type target designator is used. In this case we are targeting all methods from Knight bean.

Designator @Target

MajesticKnight class is annotated with @Primary annotation, if we want to select all methods from beans that are annotated with this annotation @target is to be used. Here is nice example for this

 

Designator within

In above example we selected join points that are located in class that is annotated or is of certain type, what if we want to select all join points in desired package ? This is where @within and within come handy

 

Conclusion

Spring AOP is offers really nice solution to your cross cutting concerns , it allows you to decouple your classes and put one concern in one place. Examples of AOP is @Transactional that I am sure you know.

Let the spring be with you 🙂

 

Write a Comment

Comment