AOP log processing in SpringBoot development tutorial
- 2021-11-29 07:13:53
- OfStack
Implementation process:
Experimental results: References: Summarize
Log processing:
Requirement analysis
What log processing needs to record is:
Requested URL Visitor IP Called method Parameters passed in Content returnedThe above content requires output in console and log.
When learning this part of knowledge, I really feel that I have gained a lot. aop, which was studied by Spring before, is only a preliminary understanding, and now I have some in-depth understanding. Good memory is better than bad writing!
In this part of log processing is mainly the use of aop, through the way of sectional integration into the project, so that the business logic between the various parts of the coupling degree reduced, improve the reusability of the program, and improve the efficiency of development.
Human words: Aop adds new functions without changing the original code
Need to know:
Crosscutting concerns: Methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to pay attention to, is the crosscutting concern. Such as logging, security, caching, transactions and so on.... Section (ASPECT): A special object whose crosscutting concerns are modularized. That is, it is a class. Notification (Advice): The work that the section must complete. That is, it is a method in the class. Entry point (PointCut): Definition of the "place" where the notifications are executed. Join point (JointPoint): The execution point that matches the pointcut.Notification (Advice) also has several methods to help implement, and here I list the methods implemented in this part:
doBefore method (executed before method), need annotation @ Before implementation After method (executed after method), need to annotate @ After implementation doAfterReturning method, requiring annotation @ AfterReturning implementationSee the following part for specific implementation.
Important part: Importing dependencies
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>test</scope>
</dependency>
Reminder: After importing the package, refresh Maven. If you can't find the package when running, try to restart it. There are many solutions on the Internet (also tried). Finally, you can use maven just by restarting it once and then refreshing it.
There is no solution here, just a reminder.
Implementation process:
Create a class (LogAspect), define the class as a section (@ Aspect) and add it to the container (@ Component).
First, create a cut-in point, and the following Advice is built on the cut-in point:
@Pointcut("execution(* com.blog.Controller..*.*(..))")
public void log(){}
The whole expression can be divided into five parts
1. execution (): Expression body.
2. The first *: indicates the return type, and the * indicates all types.
3. Package name: indicates the package name to be intercepted, and the following two periods respectively indicate the methods of all classes under the current package and all child packages of the current package, com. blog. Controller package and descendant package.
4. The second * sign: indicates the class name, and the * sign indicates all classes.
5. * (...): The third asterisk indicates the method name, the * indicates all methods, the parentheses behind it indicate the parameters of the method, and the two periods indicate any parameters
After defining the pointcut, process the pre-notification and post-notification:
@Before("log()")
public void doBefore(JoinPoint joinPoint){
System.out.println(" On entering controller Previous processing flow -------------");
}
@After("log()")
public void doAfter(){
System.out.println(" On entering controller Post-processing flow -------------");
}
// At the entry point return Cut into the content after the content (which can be used to do the processing return value 1 Some processing)
@AfterReturning(returning = "result",pointcut="log()")
public void doAfterReturning(Object result){
logger.info("Return ------ {}",result );
}
Through the above brief introduction, we can know that if we need to know the requirements in the requirements, our focus should be placed on the pre-notification, and the information of the front-end operation should be obtained before the flow processing.
The core code is as follows:
// Get the information in the request through the context
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// Gets the object that encapsulates the signature information , You can get the target method name in this object , That belongs to the class Class Such information ( Reflex )
String classMethod = joinPoint.getSignature().getDeclaringTypeName()+","+joinPoint.getSignature().getName();
// 1. Get URL
String url = request.getRequestURL().toString();
//2. Get ip Address
String addr = request.getRemoteAddr();
/* Create 1 Category RequestData To save relevant information */
RequestData requestData = new RequestData(
url, addr, classMethod, joinPoint.getArgs()
);
// Print it out on the console
logger.info("RequestData------{}",requestData);
The class created is an inner class (RequestData), which only encapsulates the information that needs to be printed under 1.
Experimental results:
Process the flow before entering controller-----
2021-08-15 15:19:43.923 INFO 9644 --- [nio-8080-exec-1] com.blog.AspectAop.LogAspect : RequestData------RequestData{url='http://localhost:8080/', ipAddr='0:0:0:0:0:0:0:1', classMethod='com.blog.Controller.IndexController,index', args=[]}
2021-08-15 15:19:43.932 INFO 9644 --- [nio-8080-exec-1] com.blog.AspectAop.LogAspect : Return ------ index
After entering controller, process the flow-----
github address of the project
References:
Crazy God said Spring
Expression parameter