This tutorial is a complete Guide to Aspect-Oriented Programming (AOP) in Spring Framework.
Aspect-Oriented Programming (AOP) is not a competitor or a replacement for Object-Oriented Programming (OOP), but it enhances and complements OOP. The concept of OOP is based on objects, while AOP concepts are based on Aspects. Both classes and aspects bring modularity and divide responsibility by modularising the structure.
This guide will emphasize acquiring a basic understanding of Aspect-Oriented Programming. It begins by knowing why the AOP framework is essential and what problems it solves. Then we will get some basic and conceptual understanding of the AOP framework and some of the most common AOP terminologies. Next, we will learn briefly about Spring AOP support and various Advices supported by Spring AOP. Finally, we will jump to the examples and tutorials demonstrating multiple aspects of Spring AOP.
Why Object-Oriented Programming (AOP)?
One of the OOP principles states that each class should have a Single Responsibility. Thus we create multiple classes to collectively process a task, where each class is responsible for taking care of particular functionality. However, some concerns break this principle, and AOP helps us solve these problems.
Single Responsibility Principle
Theoretically, an ideal Object-Oriented application has to follow SOLID principles – including the Single Responsibility Principle. However, in a practice application, we can follow the Single Responsibility Principle to an extent, but not completely. That is because we cannot have classes doing one and only one thing. The reason for that is the secondary concerns the classes have to handle. Such secondary concerns may contain logging, transaction management, or exception handling.
Another problem we face is cross-cutting concerns. Cross-cutting concerns are the secondary concerns that are applicable across multiple classes. In other words, it is a type of secondary concern that all classes need to execute. Thus, when we test the classes for their primary functionality, we also need to test them for secondary concerns.
Repeating the Cross-Cutting concerns across the classes also brings in redundancy. When we change the cross-cutting concerns at an application level, we need to change them in multiple classes. For example, each class catches exceptions generated by its functionality and throws application-specific runtime exceptions. When we change the runtime exception, we need to go and change all the classes dealing with it.
What is Aspect-Oriented Programming (AOP)?
Aspect-Oriented Programming is a software programming paradigm that brings in modularity by centralizing cross-cutting concerns. It helps impose additional behaviours on classes without modifying classes. Also, it provides means of dynamically selecting classes to which the other behaviour is applied.
The Aspect-Oriented Programming helps the classes concentrate on their core responsibilities, while the AOP components take care of the secondary concerns. Using AOP, we can centralize the cross-cutting concerns, in an Aspect, instead of repeating them across different classes.
An aspect is a shared place where we keep such crosscutting concerns. An aspect segregates such cutting concerns into an Advice. The Advice also defines Pointcut as an expression or a predicate used to select classes on which the Advice must be applied. For now, the AOP terms used here may sound unfamiliar, but in the next section, we will understand their meanings.
This section will focus on different components and concepts in Aspect-Oriented Programming.
An aspect is a concern that applies to multiple classes. An Aspect helps to segregate such concerns into a dedicated class annotated with @Aspect.
A Join Point is a point during an execution of a program. Although a JoinPoint can be any point during the execution flow, Spring AOP supports only a method execution as a JoinPoint.
Advice is the action the Aspect takes when a particular Join Point is reached. The Advice comes in different types: around, before, or after method execution. Spring AOP applies the defined advice in the form of intercepters. Also, if there are multiple advices, Spring will create a chain of interceptors.
Advice defines a Pointcut – a predicate or an expression that decides the Join Points for the Advice. Spring AOP prepares all the JoinPoints that match the Pointcut expression and applies the Advice to them.
Target Object is the Object on which an Aspect applies the Advice. We can also call it Advised Object.
For each of the target objects, Spring AOP creates proxy classes. Thus, when we auto-wire a Target Object, Spring injects the proxy for that Object.
In this section, we have learned all important AOP terminologies. If they still sound confusing, we suggest you leave it for now. Once you are well versed in AOP and practice writing Aspects and Advice, you can return and re-read. They will indeed sound familiar then.
Introduction to Spring AOP
Although Aspect-Oriented Programming is a generic concept, Spring provides excellent support. The Spring AOP support goes well with the Spring IoC container.
The AOP support in Spring is not as perfect as some other AOP frameworks. However, Spring claims that they cover all the essential aspects of AOP while keeping the framework simple. The Spring AOP emphasizes keeping the framework simple and working well with the Spring IoC container than providing a perfect AOP framework that requires additional implementations. Spring doesn’t force you to use or implement AOP components, but we can add if we want to use the Spring AOP feature.
The Spring AOP uses AspectJ internally and builds the framework based on the IoC and Dependency Injection paradigm. Some of the most common Spring features like declarative transaction management, are based on the Spring AOP feature. Spring AOP, let’s use annotations to declare an Aspect or Advice.
The Spring AOP framework’s base is the concept of dynamic proxies. The Spring AOP dynamically implements the target class’s interface to override the target method (or the JoinPoint). If a target class does not implement any interface, then Spring uses CGLIB to create proxies from the target class itself. When an AOP-enabled target class gets auto-wired, the Spring IoC container injects a dynamic proxy for that class.
Next, we will see different types of Advices supported by Spring AOP.
Types of Advice in Spring AOP
This section lists all the different types of Advice that Spring AOP supports. As stated above, Spring AOP supports method execution as a JoinPoint. Thus, we can only apply advice before and after method execution.
A Before Advice runs before method execution. The Advice cannot stop the target method execution except when the Advice throws an exception.
After Returning Advice
As the name says, an After Advice runs after the execution of the target method is finished. Note that this Advice won’t run if the target JoinPoint finishes because of execution.
An Around advice surrounds a join point execution. In other words, first, the Advice is executed, and that target method is executed from within the Advice. Thus, the execution flow moves from an Advice to the target method, executes the method, and comes back to the Advice. The Around Advice has the control to stop the target method execution.
An After Advice runs after the JoinPoint, even if the JoinPoint results in an exception. Thus, this Advice will always execute even if the target method returns successfully or ends by throwing an exception.
An After Throwing Advice runs only when a join point ends by throwing an exception. It won’t run in the scenarios when the target method returns successfully.
Spring AOP Examples and Tutorials
Spring AOP @Before Advice with Examples
Spring AOP @After Advice with Examples
Spring AOP @Around Advice with Examples
Spring AOP @AfterThrowing advice with Examples
Spring AOP Custom Annotation Example
This guide provided a detailed Introduction to Spring Aspect-Oriented Programming (AOP). We began by getting a conceptual understanding of the AOP concept and learned why it is essential. Then, we focused on various features of the AOP and understood how Spring AOP supports aspect-oriented programming. Also, we learned various concepts and terminologies used in the AOP. Finally, we learned different types of Advice that Spring supports.
For more focused, practical learning of Spring AOP, go through the individual tutorials linked in the previous section.
For more on Spring and Spring Boot, please visit Spring Tutorials.