AOP Practice for Spring Introduction: @Aspect+Pointcut+Before/Around/After

Zero. Preparing Knowledge

1) AOP related concepts: Aspect, Advice, Join point, Pointcut, Weaving, Target, etc.
  ref: https://www.cnblogs.com/zhangzongle/p/5944906.html Code examples
2) Relevant notes: @Aspect,@Pointcut,@Before,@Around,@After,@AfterReturning,@AfterThrowing
 

I. Practical Objectives

Functions of @Aspect
2)@Pointcut's Sectional Expressions
3) @Before,@Around,@After,@AfterReturning/AfterThrowing
4) reorganization and use of AOP concept
 

2. Core Code

MainController.java contains two test functions, doSomething() and test().
 1 // MainController.java
 2 @RestController
 3 public class MainController {
 4     RequestMapping(value="/doSomething", method = RequestMethod.POST)
 5     @CrossOrigin("*")
 6     public void doSomething() { 
 7         System.out.println("This is doSomething"); 
 8         test();
 9     }
10 
11     @RequestMapping(value="/justTest", method = RequestMethod.POST)
12     @CrossOrigin("*")
13     public void test() { System.out.println("This is test");}
14 }

 

ExampleAop.java defines pointcut and several Advice functions for AOP-related code.

 1 // ExampleAop.java
 2 @Component
 3 @Aspect
 4 @Order(1)
 5 public class ExampleAop {
 6 
 7     private static final Logger LOGGER = LoggerFactory.getLogger(ExampleAop.class);
 8 
 9     // matching com.example.demo All methods of all classes under a package and its subpackages
10     @Pointcut("execution(* com.example.demo..*.*(..))")
11     public void executeService() {
12     }
13 
14     @Before("executeService()")
15     public void doBeforeAdvice(JoinPoint joinPoint) throws Exception {
16         LOGGER.info("Before [{}]", joinPoint.getSignature().getName());
17     }
18 
19     @Around("executeService()")
20     public void doAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
21         LOGGER.info("Around1 [{}]", joinPoint.getSignature().getName());
22         joinPoint.proceed();
23         LOGGER.info("Around2 [{}]", joinPoint.getSignature().getName());
24     }
25 
26     @After("executeService()")
27     public void doAfterAdvice(JoinPoint joinPoint) throws Exception {
28         LOGGER.info("After [{}]", joinPoint.getSignature().getName());
29     }
30 
31     @AfterReturning("executeService()")
32     public void doAfterReturningAdvice(JoinPoint joinPoint) throws Exception {
33         LOGGER.info("AfterReturning [{}]", joinPoint.getSignature().getName());
34     }
35 }

 

Compile and run the jar package and call the interface / doSomething.

1 # Call interface
2 curl localhost:8080/doSomething

 

Go to the server and observe the log.

1 <!-- Background log -->
2 com.example.demo.aop.ExampleAop          : Around1 [doSomething]
3 com.example.demo.aop.ExampleAop          : Before [doSomething]
4 This is doSomething
5 This is test
6 com.example.demo.aop.ExampleAop          : Around2 [doSomething]
7 com.example.demo.aop.ExampleAop          : After [doSomething]
8 com.example.demo.aop.ExampleAop          : AfterReturning [doSomething]

 

III. Analysis and conclusions

Functions of @Aspect
Add processing around the join point. In this case, doSomething() is the join point, while test() is not.
Is only the outermost join point inserted by Advice? In the latter part, we will make a simple discussion and guess.
 
 
2)@Pointcut's Sectional Expressions
  ref: https://www.cnblogs.com/liaojie970/p/7883687.html Common expressions
  ref: https://www.jianshu.com/p/fbbdebf200c9 Complete expression
@ Pointcut("execution(...)") is a Pointcut expression and executeService() is a point signature. Expressions can contain logical operations of signatures.
 
Common expressions:
1 execution(public * com.example.demo.ExampleClass.*(..))  // ExampleClass All public methods
2 execution(* com.example.demo..*.*(..)) // com.example.demo All methods under packages and their subpackages
3 logSender() || logMessage() // The union of two signature expressions

 

 

3) @Before,@Around,@After,@AfterReturning/AfterThrowing
@ Around 1 - > @Before - > Method - > @Around 2 - > @After - > @AfterReturning/ @AfterThrowing (additional discussion on timing issues later).
In addition, it can be found that @Around can affect the execution of the program itself, without calling joinPoint.proceed(); the method will not be executed. None of the others can affect program execution.
 
 
4) reorganization and use of AOP concept
Aspect (aspect): The @Aspect annotation is used, such as the ExampleAop class.
Advice: Enhancement operations at specified locations, such as method runtime statistics, user login, logging, etc. Annotations such as @Before, @After, etc., such as the doBeforeAdvice() method.
Weaving: AOP is a mechanism for weaving Advice (i.e., embedding, inserting) into a specified location in Aspect to execute.
Join point: The location where the Advice is executed, which is also a parameter of the Advice, is a specific method. The doSomething() function as seen in the log.
Pointcut: An expression that represents a set of join point s for defining the role of Advice by the @Pointcut annotation. For example, @Pointcut("execution(* com.example.demo. *. * (.))") represents all methods of all classes under the com.example.demo package and its subpackage.
Target: Enhanced objects, i.e. objects containing classes of primary business logic, such as instances of ExampleAop classes.

 

IV. Questions and Discussion

1. This article says the order of execution is @Around 1-> @Before-> Method-> @Around 2-> @After, but some articles say @Before-> @Around 1-> Method-> @Around 2-> After, and others say @Around 1-> @Before-> Method-> @After-> @Around 2, which is right?
 
Anyway, the code runs in this order, that's the order. There is no change in the pull-up time of each Advice plus sleep. I don't know if it's affected by the version or the code itself.
In a word, we can draw a conclusion that @Before/After is better not to mix with @Around and the execution order is not well determined.
The timing is at least always satisfied: @Around1/Before-> method->@Around2/After->@AfterReturning/AfterThrowing
 
 
2. Why are doSomething() and test() both selected action nodes in @Pointcut, but only doSomething() inserts Advice, and test() does not?
 
A guess: literally, @Pointcut cuts all code with expressions as rules, with all joinpoint s on one side and plain code on the other. Insert a layer of Advice agent between the join point and the code on the other side. If the code on the other side wants to call the join point, it must be enhanced by Advice. Different join points are on the same side, so Advice is not inserted.
There is time to read the source code again to understand the mechanism.

(A guess)

 

Future Work

1. There are also some concepts in AOP, such as Advisor, to be learned.
2. Sectional expressions (@Pointcut expressions) are rich in rules and need to be learned.
3. Advice insertion timing, to read source learning.

 

Keywords: Java curl

Added by harrisonad on Tue, 27 Aug 2019 18:44:13 +0300