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)