0. Preface
This paper is divided into two parts. The upper part is the basis of AOP aspect technology to learn the spring boot AOP aspect technology.
The lower part is the practice, which uses AOP aspect technology to create a unified login log for restful API interface.
1. Introduction to AOP section programming
There is a scenario in which a master data management system of a company has been put into operation, but the system is unstable and sometimes runs very slowly. In order to detect what is wrong, developers need to monitor the execution time of each method, and then judge the problem according to the execution time. When the problem is solved, the monitoring needs to be removed.
Because the system has been put into operation, if thousands of methods in the system are manually modified, the workload will be very large, and these monitoring methods will have to be removed in the future, which is time-consuming and laborious. If you can dynamically add code when the system is running, you can solve this requirement. Objective: the monitoring output can be realized without modifying the source code. At this time, AOP aspect programming is the best choice.
The method of dynamically adding code when the system is running is called "aspect oriented programming AOP". It uses horizontal extraction mechanism to replace the traditional vertical inheritance system of repetitive code. It has many application scenarios:
A: System monitoring, execution analysis, performance statistics.
B: Set logs to record login, execution, parameters and other information.
C: Interception, fine interception and security control can be quickly realized through AOP.
D: Transaction processing and unified exception handling.
In short, AOP is like taking a CT of a program and slicing the execution process.
2. Common AOP concepts
- Joinpoint: a join point is a method that can be enhanced in a class. For example, if you want to modify the function of which method, this is a join point.
- Pointcut: pointcut, that is, the definition of intercepting joinpoints is the pointcut. For example, intercepting all methods starting with select is a pointcut.
- Advice: notification. After intercepting the Joinpoint, all you need to do is notify, such as printing logs, sending emails, writing monitoring, etc.
- Aspect: the combination of aspect, Pointcut and Advice.
- Target: the class to be enhanced is called target.
3. Fundamentals of spring boot AOP aspect Technology
3.1 add Maven dependency
<!-- AOP Aspect oriented programming--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
The project structure is shown in the figure below:
3.2 create a UserService service class and a UserController interface implementation class to call the UserService service class.
We're on COM example. demohelloworld. AOP. Create a UserService service class under the service package. The code is as follows:
package com.example.demohelloworld.AOP.Service; import org.springframework.stereotype.Service; @Service public class UserService { //Define a simple query method public String getUserById(Integer id){ System.out.println("get>>>"+id); return "getuser"; } //Define a simple delete method public void deleteUserById(Integer id){ System.out.println("delete>>>"); } }
We're on COM example. demohelloworld. Create a UserController interface class under the AOP package. The code is as follows:
package com.example.demohelloworld.AOP; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; //It is used to call UserService and execute the test in the foreground @RestController public class UserController { @Autowired UserService userservice; @GetMapping("/getuser/{id}") public String getUserById(@PathVariable Integer id){ return userservice.getUserById(id); } @GetMapping("/deleteuser") public void deleteUserById(Integer id){ userservice.deleteUserById(id); } }
3.3 next, create the AOP facet class AspectLog
We're on COM example. demohelloworld. Create AspectLog facet class under AOP package. The code is as follows:
package com.example.demohelloworld.AOP; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import java.util.Arrays; @Component //@The Aspect annotation indicates that this is an Aspect class @Aspect public class AspectLog { //Define the pointcut. The first * in execution indicates that the method returns any value, the second * indicates any class under the AOP package, the third * indicates any method in the class, and the two points in parentheses indicate any value of the method parameter @Pointcut("execution(* com.example.demohelloworld.AOP.Service.*.*(..))") public void pointcutvoid(){ } //@The Before annotation indicates that this is a pre notification that the method executes Before the target method executes. The method name, modifier and other information of the target method can be obtained through the JoinPoint parameter @Before(value = "pointcutvoid()") public void before(JoinPoint joinPoint){ //Get incoming parameters Object[] args =joinPoint.getArgs(); System.out.println(joinPoint.getSignature().getName()+"Method starts execution...The parameters passed in are:"+Arrays.deepToString(args)); } //@The After annotation indicates that this is a post notification, and the method is executed After the target method is executed @After(value = "pointcutvoid()") public void after(JoinPoint joinPoint){ System.out.println(joinPoint.getSignature().getName()+"End of method execution..."); } //@The AfterReturning annotation indicates that this is a return notification. In this method, the return value of the target method can be obtained. The returning parameter refers to the variable name of the return value and the parameter of the corresponding method. The type of result defined in the method parameter is Object, which means that the return value of the target method can be of any type. If the type of result parameter is Long, the method can only handle the case that the return value of the target method is Long @AfterReturning(value = "pointcutvoid()",returning = "result") public void afterReturning(JoinPoint joinPoint,Object result){ System.out.println(joinPoint.getSignature().getName()+"The return value of the method is:"+result); } //@The AfterThrowing annotation indicates that this is an Exception notification, that is, when an Exception occurs in the target method, the method will be called. The Exception type is Exception, which means that all exceptions will be executed in the method. If the Exception type is ArithmeticException, it means that only the ArithmeticException Exception thrown by the target method will be processed in the method @AfterThrowing(value = "pointcutvoid()",throwing = "ex") public void afterThrowing(JoinPoint joinPoint,Exception ex){ System.out.println(joinPoint.getSignature().getDeclaringTypeName()+joinPoint.getSignature().getName()+"The method is abnormal. The exception is:"+ex.getMessage()); } //@The Around annotation indicates that this is a surround notification. The surround notification is the most powerful notification among all notifications. It can realize the functions of pre notification, post notification, exception notification and return notification. After the target method enters the surround notification, call the processed method of the proceed ingjoinpoint object to continue the execution of the target method. The developer can modify the execution parameters and return values of the target method here, and handle the exceptions of the target method here @Around("pointcutvoid()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ return proceedingJoinPoint.proceed(); } }
3.3. The @ Aspect annotation indicates that this is an Aspect class.
3.3. 2. The @ Pointcut annotation is used in the pointcutoid () method, indicating that this is a Pointcut.
The entry point in this article is @ Pointcut("execution(* com.example.demohelloworld.AOP.Service. * (..)")
The first * in execution indicates that the method returns any value, the second * indicates any class under the Service package, the third * indicates any method in the class, and the two points in parentheses indicate any value of the method parameters.
We can define the content to be cut according to needs from three levels: package, class and method.
3.3. 3. We also need to understand the meaning of section annotation:
Section annotation | Annotation meaning | Detailed meaning |
---|---|---|
@Before | Front | Indicates that this is a pre notification, and the method is executed before the target method is executed. The method name, modifier and other information of the target method can be obtained through the JoinPoint parameter |
@AfterThrowing | Exception thrown | Indicates that this is an Exception notification, that is, when an Exception occurs in the target method, the method will be called. The Exception type is Exception, which means that all exceptions will enter the method for execution. If the Exception type is ArithmeticException, it means that only the ArithmeticException Exception thrown by the target method will enter the method for processing |
@After | Post | Indicates that this is a post notification, and the method is executed after the target method is executed |
@AfterReturning | Post enhancement, execution order After @ After | Indicates that this is a return notification. In this method, the return value of the target method can be obtained. The returning parameter refers to the variable name of the return value and the parameter of the corresponding method. The type of result defined in the method parameter is Object, which means that the return value of the target method can be of any type. If the type of result parameter is Long, the method can only handle the case that the return value of the target method is Long |
@Around | surround | Indicates that this is a surround notification, which is the most powerful notification among all notifications. It can realize the functions of pre notification, post notification, exception notification and return notification. After the target method enters the surround notification, call the processed method of the proceed ingjoinpoint object to continue the execution of the target method. The developer can modify the execution parameters and return values of the target method here, and handle the exception of the target method here |
3.3. 4. The JoinPoint object of the connection point encapsulates the execution information of the AOP aspect method (this is the information we need to refine, which can be used as monitoring, log, etc.), so we also need to understand the meaning of the common methods of getSignature() in the JoinPoint:
method | Method meaning |
---|---|
joinPoint.getSignature().getDeclaringTypeName() | Get the path and name of the cut class, for example: com example. demohelloworld. AOP. UserService |
joinPoint.getSignature().getName() | Get the name of the method in the cut class, for example: getUserById or deleteUserById in this article |
joinPoint.getArgs() | Gets the parameter object passed into the target method |
joinPoint.getTarget() | Gets the proxy object |
3.4 start the project and start testing the section effect
Open browser input http://localhost:8080/getuser/1 , AOP cut the getUserById. The background effect is as follows:
input http://localhost:8080/deleteuser , AOP cut the deleteUserById. The background effect is as follows:
4. AOP summary
AOP aspect oriented programming refers to extending the function without modifying the source code and separating the function code from the business logic code. Then realize the functions of logging, performance statistics, security control, transaction processing, exception handling and so on.
The application of aspect technology greatly improves the scalability, security and convenience of the program, and is very friendly to developers. With less code, it can complete the functions of monitoring, logging and interception, and greatly improve the development efficiency.
Next, I will use a practical case: using AOP aspect technology to create a unified login log for restful API interface without modifying any original interface code, so that you can further understand the advantages of AOP aspect technology.