Spring AOP enables Aspect-Oriented Programming in Spring applications. Aspect increases modularity by allowing the separation of cross-cutting concerns such as logging, transaction, and security
Say you have multiple REST APIs need to implement authentication, then you can use AOP to write the security logic once only and apply to all of them without modifying their code
In Spring Frameworks, Spring AOP is used for
Providing declarative enterprise services such as transaction management
Letting user implement custom aspects
Let walk through this tutorial to explore in more details
AOP concepts
Aspect: A modularization concern, such as logging, transaction or security, that cut multiple classes
Join point: A point in your program execution where an aspect can be intercepted in. This point could be a method being called or an exception being thrown
Advice: Action taken by an aspect at a particular join point. Different types of advice include "around", "before" and "after" advice
Pointcut: A predicate that matches join points. Spring AOP only supports method execution join points for Spring beans
Target object: An object being advised by one or more aspects, also referred to as the "advised object". In Spring AOP, this object is always a proxied object
AOP proxy: An object created by the AOP framework in order to implement the aspect contracts
Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time (using AspectJ compiler) or runtime (using Spring AOP)
Add Spring AOP into your project
Add spring-boot-starter-aop
into your project as a dependency on pom.xml
or build.gradle
file. The library versions can be omitted as it is resolved by the parent pom provided by Spring Boot
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
AspectJ annotations support
Spring AOP can support AspectJ annotations to declare aspects, pointcuts, and advice. The runtime is still pure Spring AOP, though
@EnableAspectJAutoProxy
is used for enabling support for handling components marked with AspectJ annotations. In Spring Boot,@EnableAspectJAutoProxy
is auto-enabled when the propertyspring.aop.auto=true
(default)Declare an aspect with
@Aspect
, add@Component
to autodetecting it through component scanning
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
}
- Declare a pointcut name by declaring a method signature (must have
void
as return type) and expression with@Pointcut(expression)
@Pointcut("execution(* commandLineRunner(..))")
private void commandLineRunner() {}
- Declare advice which with either
@Around
,@Before
,@After
,@AfterThrowing
or@AfterReturning
. Advice is associated with an inline or named pointcut expression
@Around("commandLineRunner()") // named pointcut
@Around("execution(* commandLineRunner(..))") // inline pointcut expression
Implement a custom aspect example
Now you have seen all the parts. Lets wire things together to implement an aspect to log the execution time of a method in Spring applications. Learn more at https://hellokoding.com/spring-aop-custom-annotation-example/
Spring AOP limitations
Due to the proxy-based nature of Spring AOP, calls within the target object are not intercepted
Apart from that, only public methods in case of JDK proxies while public and protected methods in case of CGLIB proxies are intercepted
If you'd like to get over the limits, consider using AspectJ native weaving
Conclusion
In this tutorial, we had a quick look at AOP concepts, AspectJ annotations support in Spring AOP and how to use Spring AOP to implement a custom aspect. You can find the source code at GitHub https://github.com/hellokoding/hellokoding-courses/tree/master/spring-examples/spring-aop-example