This article is about aspect oriented programming (aop) in spring. the related example of an application with aop support is in the following address :
https://github.com/ghorbanihamid/SpringBoot_AOP_JPA_Example
1. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
1
Aspect Oriented Programming(AOP):
Before we start Learning AOP, first let’s review other programming paradigms: Functional Programming
and Object Oriented Programming.
1. Functional Programming:
In older programming language like C, we have used functional programming style. In this programming
model, software designers tend to use Top-Down approach, in which the overall objective of the system is
defined first. Then the system is divided into various sub tasks or sub modules. With this methodology,
software development is done by writing a set of sub programs, called functions that can be integrated
together to form a complex system.
In functional programming, the primary focus is on functions. A function is a sub program that performs
a specific task using the values given to it through input variables (called parameters) and then returns
the result to its calling function. Dividing the program into functions is the key to functional programming,
so a number of different functions are written in order to accomplish the tasks. The main problem in this
style of programming is complexity, it is very messy style of coding to write big project programming. In
this approach, very little attention is given to data used by the function. As most of the functions share
global data, they move independently around the system from function to function, thus making the
program vulnerable.
2. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
2
2. Object Oriented Programming(OOP):
Object oriented programming is a programming approach that focuses on data rather than the
algorithm. In this style of programming we would not think about function when we trying to solve
problem, we would think as individual entities as object. Objects are data structures that contain data,
in the form of fields (or attributes) and codes in the form of procedures (or methods). These object interact
with each other by sending messages.
Systems are composed of several components, each responsible for a specific piece of functionality. But
often these components also carry additional responsibilities beyond their core functionality. System
services such as logging, transaction management, and security often find their way into components
whose core responsibilities is something else. These system services are commonly referred to as cross-
cutting concerns because they tend to cut across multiple components in a system.
Let’s try solve the above problem with OOP, the first solution that come to mind is; putting logMessage
method in every object but this is not a good idea for the above problem, because logMessage method is
3. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
3
repeating in each class. Another better solution is creating a Logger class and putting logMessage mothed
in it, now whichever object requires this functionality, can call the Logger object:
But we still have Problems with above approach:
We still need to write the code in all the methods to call the logger object logMessage(). Any changes
in future will require changes in all method.
Too many relationship (while designing) with the Logger class which actually doesn’t have any
business logic or is not important.
So, OOP has given us tools to reduce software complexity by introducing concepts like inheritance,
abstraction, and polymorphism. However, developers face daily problems like cross-cutting concerns in
software design that can't be solved easily using OOP. Aspect-Oriented Programming (AOP) tries to solve
these problems by introducing the concept of separation of concerns, in which concerns can be
implemented in a modular and well-localized way.
3. Aspect Oriented Programming(AOP):
Aspect-Oriented Programming (AOP) complements Object-Oriented Programming by providing another
way of thinking about program structure. It was built as a response to limitations of OOP. AOP is often
defined as a technique that promotes separation of program logic into distinct parts (concerns) in a
software system. Today, multiple AOP frameworks are available. AspectJ and SpringAOP are two
dynamics, lightweight and high-performant AOP framework for Java. Spring AOP’s aim is to provide a
close integration between AOP implementation and Spring IoC to help solve common problems in
enterprise applications. Spring provides support for using AspectJ annotations to create aspects.
4. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
4
Enabling AspectJ Annotations with Spring:
With Spring, you can declare advice using AspectJ annotations, but you must first apply the
@EnableAspectJAutoProxy annotation to your configuration class, which will enable support for
handling components marked with AspectJ’s @Aspect annotation:
@Configuration
@ComponentScan(basePackages = . . .})
@EnableAspectJAutoProxy
public class TestConfig {
...
}
AOP Terminologies:
Before we start working with AOP, let us become familiar with the AOP concepts and terminology. These
terms are not specific to Spring, rather they are related to AOP.
Aspect:
The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect.
aspect is a module which has a set of APIs providing cross-cutting requirements. For example, a logging
module would be called AOP aspect for logging. An application can have any number of aspects depending
on the requirement. In Spring AOP, aspects are implemented using regular classes (the schema-based
approach) or regular classes annotated with the @Aspect annotation (the @AspectJ style).
@Aspect
public class LoggingAspect {
. . .
}
Join point:
A Join Point is a point in the execution of the application where an aspect can be plugged in. This point
could be a method being called, an exception being thrown, or even a field being modified.
5. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
5
Advice
This is the actual action to be taken either before or after the method execution. This is an actual piece of
code that is invoked during the program execution by Spring AOP framework. In Spring, an Advice is
modeled as an interceptor, maintaining a chain of interceptors around the Joinpoint. Advice is the
implementation of Aspect. We have 5 type of advices: Before, After, AfterReturning, AfterThrowing and
Around.
@Aspect
public class LoggingAspect {
//Advice
public void logBefore(…) {
. . .
}
}
Pointcut
Pointcuts are expressions that are matched with Join points to determine whether advice needs
to be executed or not. Advice is associated with a pointcut expression and runs at any join point
matched by the pointcut. A pointcut expression starts with a pointcut designator (PCD), which is a
keyword telling Spring AOP what to match. There are several pointcut designators, such as:
@execution, @within, @args, @annotation and @target.
Example1: " execution(public String com.soshiant.service.UserService.getUsersList())"
This pointcut will match exactly the execution of getUsersList method of the UserService class.
Example2: "execution(public String getName())"
This pointcut means, the advice will execute for any Spring Bean method with signature public
String getName().
Example3: "execution(* com.soshiant.service.*.get*())"
This pointcut means, the advice will be applied for all the classes in com.soshiant.service
package whose name starts with get and doesn’t take any arguments.
6. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
6
Example4: "execution(public**(..))"
This pointcust will be applied on all the public methods.
Example5: "within(com.soshiant.service..*)"
This pointcust will be applied on all Types within the service package.
Note: Sometimes we have to use same Pointcut expression at multiple places, we can create an empty
method with @Pointcut annotation and then use it as expression in advices.
Example4:
//Pointcut to execute on all the methods of classes in a package
@Pointcut("execution(* com.soshiant.service.*.get*()")
public void allMethodsPointcut(){
}
Introduction
An Introduction allows adding new methods or attributes to existing classes. The new method and
instance variable can be introduced to existing classes without having to change them, giving them new
state and behavior. Spring AOP allows you to introduce new interfaces (and a corresponding
implementation) to any advised object.
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 contracts (advise method
executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB
proxy.
7. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
7
Weaving
Weaving is the process of applying aspects to a target object to create a new proxied object. This can be
done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP,
like other pure Java AOP frameworks, performs weaving at runtime.
Type of of advices:
Before Advice: it executes before a method execution (join point method). We can use @Before
annotation to mark an advice type as Before advice. The string parameter passed in the @Before
annotation is the Pointcut expression
Example1:
@Before(execution(public String getName()))
public void logGetNameMethods(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
logger.info("Before " + methodName);
}
In the above example, logGetNameMethods() advice will execute for any Spring Bean method with
signature public String getName().
Example2:
@Before(execution(* com.soshiant.service.*.get*()))
public void logAllGetMethods(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
logger.info("Before " + methodName);
}
In the above example, logAllGetMethods() will be applied for all the classes in
com.soshiant.service package whose name starts with get and doesn’t take any arguments.
8. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
8
After Advice(finally): it executes after a method execution (join point) regardless of its
outcome (regardless of join point exit whether normally or exceptional return). We can use @After
annotation to mark an advice type as Before advice.
After Returning Advice: it executes after a method execution (joint point), only if it completes
successfully. We can use @AfterReturning annotation to mark an advice type as Before advice.
After Throwing Advice: it executes if method exits by throwing an exception. We can use
@AfterThrowing annotation to mark an advice type as Before advice.
Around Advice: It executes before and after a join point. We can use @Around annotation to
mark an advice type as Before advice.
9. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
9
Spring AOP Example:
In this example, we will add logging aspect to our spring application. Let’s start by adding Spring’s AOP
library dependency in the pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${version.spring-framework}</version>
</dependency>
If you are using Spring boot:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${version.springboot}</version>
</dependency>
Add AspectJ dependency in pom.xml:
<dependency>
<groupId>org.aspectj </groupId>
<artifactId>aspectjrt</artifactId>
<version>${version. aspectj}</version>
</dependency>
<dependency>
<groupId>org.aspectj </groupId>
<artifactId>aspectjweaver</artifactId>
<version>${version.aspectj}</version>
</dependency>
User Model:
public class UserInfo implements java.io.Serializable {
private String userFirstName;
private String userLastName;
private String username;
private String password;
}
10. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
10
User Service:
public interface UserService {
public boolean saveNewUser(UserInfo userInfo);
public List<UserInfo> getUsersList();
}
User ServiceImpl:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public boolean saveNewUser(UserInfo userInfo) {
userDao.saveNewUser(userInfo);
return true;
}
public List<UserInfo> getUsersList(){
List<UserInfo> userInfoList = userDao.getAllUsers();
return userInfoList;
}
}
LoggingAspect:
@Aspect
public class LoggingAspect {
@Before("execution(*com.soshiant.service.users.
UserServiceImpl.addNewUser(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("LoggingAspect.logBefore() is running!");
System.out.println("Method Name : " +
joinPoint.getSignature().getName());
}
}
11. Hamid Ghorbani (Spring AOP) https://ir.linkedin.com/in/ghorbanihamid
11
Above Example on Github:
h ps://github.com/ghorbanihamid/SpringMVC5_AOP_Example
https://github.com/ghorbanihamid/SpringBoot_AOP_JPA_Example
Resources:
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop
http://jonasboner.com/real-world-scala-managing-cross-cutting-concerns-using-mixin-composition-and-aop/
https://www.javatpoint.com/spring-aop-tutorial
http://www.baeldung.com/spring-aop
https://www.tutorialspoint.com/spring/aop_with_spring.htm
https://djcodes.wordpress.com/frameworks/spring-aop-basics/
https://www.dineshonjava.com/introduction-to-aop-in-spring/
https://howtodoinjava.com/spring/spring-aop/spring-aop-aspectj-example-tutorial-using-annotation-config/