Spring AOP: A Go through with Simple Example
I am assuming that you are aware of what is Aspect Oriented Programming and its use in applications. I will briefly describe some AOP concepts and terminology. These terms are not Spring-specific.
- Aspect: It is a general feature that you can apply to your application globally. It allows you to add common behaviour to your module without interfering in your business logic. (like logging, performance monitoring, exception handling, transaction management, etc).
- Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
- Advice: action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice. It is a piece of code that should be executed at specific aspect. Like you want to execute some logging before any method invocation aspect.
- Pointcut: a predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
- Target object: object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.
- AOP proxy: an object created by the AOP framework in order to implement the aspect methods (advice method executions).
Types of Advice:
- Before advice: Advice that executes before a join point.
- After returning advice: Advice to be executed after a join point completes normally: for example, if a method returns without throwing an exception.
- After throwing advice: Advice to be executed if a method exits by throwing an exception.
Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans). Field interception is not implemented, although support for field interception could be added without breaking the core Spring AOP APIs. If you need to advise field access and update join points, consider a language such as AspectJ.
Spring And Advice:
We will start with advices. Advice implementations in Spring are simply implementations of the org.aopalliance.intercept.MethodInterceptor interface. But that’s not a Spring class. Spring’s AOP implementation uses a standard AOP API from the AOP Alliance (JAVA/J2EE AOP standards). The MethodInterceptor interface is actually a child of the org.aopalliance.intercept.Interceptor interface, which is a child of another interface, org.aopalliance.aop.Advice.
The MethodInterceptor interface is very simple:
Basically, when you write an advice for intercepting a method, you have to implement one method – the
invokemethod, and you are given a
MethodInvocationobject to work with. The
MethodInvocationobject gives different operations about the method that we’re intercepting, and also gives a hook to tell the method to go ahead and run.
Spring has multiple alternatives to the basic MethodInterceptor.They allow you to do more specific things related to advice. They include:
- org.springframework.aop.MethodBeforeAdvice - Implementations of this interface have to implement this method:
All you need to do is do what you need before the method is called (as the interface name implies).
- org.springframework.aop.AfterReturningAdvice - This interface’s method will be called on the return from the invocation of a method. The method looks like this:
You’ll notice it looks a whole like the before advice, but simply adds the Object’s return value to the method arguments.
- org.springframework.aop.ThrowsAdvice - Instead of requiring you to implement a particular method, this is simply a ‘marker’ interface, and expects you to implement any number of methods that look like this:
Spring And PointCuts:
Point cut is a predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default. Pointcuts in Spring implement the org.springframework.aop.Pointcut interface and look like this:
The method matcher simply describes which methods for a given class are considered valid joinpoints for this pointcut.
Spring has different implementation for static vs. dynamic method matching point cuts. Astatic method matcher pointcut knows at a runtime that which method to be considered as join point on that object. While a dynamic method matcher consulted at every method invocation (to determine which is valid joint point).
Dynamic method matcher includesorg.springframework.aop.support.JdkRegexpMethodPointcut and org.springframework.aop.support.PerlRegexpMethodPointcut classes.
A static method matcher, while having less flexibility (you can’t check the method invocation arguments), is, by design, much faster, as the check is only performed once, rather than at every method invocation. Static Matching pointcuts implementations look like this:
This requires implementing just one abstract method (although it’s possible to override other methods to customize behavior). It will be a joint point of any advice if executing method name contains string “aspect”.
Now we have to tie a point cut with advices. The most basic pointcut advisor is the org.springframework.aop.support.DefaultPointcutAdvisor class. We can do this by following definition in spring file.
Now, lets’ glue them all together and create very simple example of Spring AOP. I have a test bean which has a string attribute. We will change that attribute in an advice.
Spring AOP Proxy:
The basic way to create an AOP proxy in Spring is to use the ProxyFactoryBean. This gives complete control over point cuts and advice that will apply.
Following is my test proxy bean.