Spring AOP allows developers to intercept code that executes before and after methods calls. Aspects enable the modularization of crosscutting concerns such as transaction management, security or logging.
Here are a few key terms that you'll encounter when dealing with AOP.
Advice
- is the action taken by an aspect at a particular joinpoint.
Joinpoint
- is the point at which a method or the handling of an exception occurs.
Pointcut
- an expression language of spring AOP which is basically used to match the target methods to apply the advice.
- Pointcut expressions can be combined using operators like ||, && and ! but in our example we won't be using this technique
-
syntax: Advice(" execution(modifiers? return-type declaring-type? method-name(param) throws?) ")
@Before("execution(public Integer com.company.service.*.add*(..))")_
Example
0. Structure your packages
ex:
com.company
com.company.aop
com.company.service
1. Add to Maven /pom.xml
<!-- aop dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. Create your AOP class and apply annotations
com.company.aop.MyCustomAspect
@Aspect // import from org.aspectj.lang.annotation.Aspect
@Component
public class MyCustomAspect{
// code goes here..
}
3. Add any of these Advice method into your AOP class
Before advice
@Before("execution(public Integer com.company.service.*.add*(..))")
public void beforeLoggingAdd() {
System.out.println("### LOG: advice that runs BEFORE the method ###");
}
After advice
@After("execution(public Integer com.company.service.*.add*(..))")
public void afterLoggingAdd() {
System.out.println("### LOG: advice that runs AFTER the method ###");
}
After Returning advice
an optional returning="return" can be used to access the return value of the matched method
@AfterReturning(pointcut = "execution(public Integer com.company.service.*.add*(..))", returning = "result")
public void afterReturningLoggingAdd(Object result) {
System.out.println("### LOG: advice that runs AFTER the methods's successful execution ###");
System.out.println("result: " + result.toString());
}
After Throwing advice
@AfterThrowing(pointcut = "execution(public Integer com.company.service.*.add*(..))", throwing = "throwingException")
public void afterExceptionLoggingAdd(Throwable throwingException) {
System.out.println("### LOG: advice that runs after the method (if exception is thrown) ###");
System.out.println("exception: " + throwingException);
}
Around advice
this advice can perform custom behavior both before and after the method invocation
@Around("execution(public Integer com.company.service.*.add*(..))")
public Integer aroundLoggingAdd(ProceedingJoinPoint jp) throws Throwable {
System.out.println("### LOG: advice that runs BEFORE and AFTER the method ###");
Integer result = (Integer) jp.proceed();
System.out.println("### LOGGING ADD METHOD : AROUND ###");
return result;
}
4. Create a method to execute
com.company.service.MyService
@Service
public class MyService {
public Integer addResource(){
System.out.println("add method executed!");
return 0;
}
}
5. Test your AOP advice
com.company.DemoApplication
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
MyService ms;
@Override
public void run(String... args) throws Exception {
ms.addResource();
}
}
Top comments (0)