Basic concepts:
AOP: Aspect Oriented Programming, facet-oriented programming
A programming method that dynamically cuts a piece of code into a specified location for a specified method to run while the program is running
- Pre-notification (@Before): Executes before the target method runs
- Post-notification (@After): executes after the target method has finished running (whether the method executes successfully or an exception occurs)
- Return notification (@AfterReturning): executes after the target method returns normally
- Exception notification (@AfterThrowing): executes after the target method has an exception
- Wrap notification (@Around): Dynamic proxy that manually advances the target method run (joinPoint.procced)())
Only one return notification and exception notification can be executed simultaneously
Basic use:
-
Importing aop dependencies: Spring AOP (spring-aspects)
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency>
-
Define a business logic class
public class MathCalculator { public int div(int a, int b){ return a / b; } }
-
Define a log facet class that tells Spring that it is a facet class (add: @Aspect to the facet class) and label the target method ** "when and where"** to execute (notification note)
-
Entry Point Basic Format: Privilege modifier method return value Full method name (parameter list type) exception type, bold required
-
References on the @Before annotation require full method names if referencing an entry point expression outside of a class
@Aspect public class LogAspects { //Extracting common entry point expressions @Pointcut("execution(* com.spring.aop.MathCalculator.*(..))") public void pointCut(){ } @Before("pointCut()") public void logStart() { System.out.println("Method Run"); } @After("pointCut()") public void logEnd() { System.out.println("Method End"); } @AfterReturning("pointCut()") public void logReturn() { System.out.println("Method returns normally"); } @AfterThrowing("pointCut()") public void logException() { System.out.println("Method has an exception"); } }
-
-
Register both the facet class and the business logic class (the class where the target method is located) into the ioc container, referring to the previous blog for several ways to register Spring Annotations - Registration of Components
@Bean public MathCalculator mathCalculator(){ return new MathCalculator(); } @Bean public LogAspects logAspects(){ return new LogAspects(); }
-
Turn on annotation-based AOP mode (add: @EnableAspectJAutoProxy to the configuration class)
@Configuration @EnableAspectJAutoProxy public class SpringConfiguration
-
Test one
@Test public void test1(){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration6.class); MathCalculator mathCalculator = (MathCalculator) applicationContext.getBean("mathCalculator"); mathCalculator.div(2, 1); }
Run result:
----- Normal operation----- Method Run Method End Method returns normally --------- Exception------- Method Run Method End Method has an exception
But the above output is too simple, what if you want specific information about the method?We've made some improvements to the noodle class
@Aspect public class LogAspects { @Pointcut("execution(* com.spring.aop.MathCalculator.*(..))") public void pointCut() { } @Before(value = "pointCut()") public void logStart(JoinPoint joinPoint) { //parameter list Object[] args = joinPoint.getArgs(); //Method Name String methodName = joinPoint.getSignature().getName(); System.out.println(methodName + "Method runs, parameter list:" + Arrays.toString(args)); } @After("pointCut()") public void logEnd(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println(methodName + "Method End"); } @AfterReturning(value = "pointCut()", returning = "returnInfo") public void logReturn(JoinPoint joinPoint, Object returnInfo) { String methodName = joinPoint.getSignature().getName(); System.out.println(methodName + "The method returns normally with a return value of:" + returnInfo); } @AfterThrowing(value = "pointCut()", throwing = "exception") public void logException(JoinPoint joinPoint, Exception exception) { String methodName = joinPoint.getSignature().getName(); System.out.println(methodName + "Method has an exception, exception information:" + exception); } }
Run result:
----- Normal operation----- The div method runs with a list of parameters: [2, 1] div method end The div method returns normally with a return value of 2 --------- Exception------- The div method runs with a list of parameters: [2, 0] div method end The div method has an exception, exception information: java.lang.ArithmeticException: / by zero
Note: The parameter joinPoint must be placed first in the parameter table