Using Spring Aop, a note for logging
1. Introduction
We all know that the two main features of the Spring Framework are IOC (Control Inversion) and AOP (Face Oriented), which are mentioned at the beginning of every Spring learning video. In daily projects, we often use IOC to control inversion, but feel that AOP is rarely used. In fact, AOP can be very useful and even make you lazy.
For example, what would you do if you were to record each request's request IP, method of request, request path, request parameters, and return parameters now? You would think, that's easy, I log directly. Info ("xxxx") output log not work, simple! But you want to be clear that each request may not have the same method, some may request editing methods, others may request login methods. With so many methods, you have written about 6 or 7 lines of duplicate code under each method. Do you think this is good?
Here, it would be great if we used Aop to log. We can look at the execution of a method to understand AOP.
Next, let's look at the execution process after using AOP.
AOP is face-oriented programming, the face-oriented idea is to let us imagine the program as a large pipeline connected by a pipeline, while AOP is a filter between the pipeline and the pipeline, which can record and modify the data transferred in the pipeline without affecting the pipeline.
With AOP, we can easily log operations, performance logging, request logging, transaction operations, security management, and so on. This may be abstract, and more specifically, all kinds of logging can be recorded using AOP instead of inserting in business logic code. Security management means that we can decrypt the data in the request before the request comes in and encrypt the data when the request returns. So AOP is like a combination of interceptors, filters and monitors in Java.
The principle of AOP is not detailed. That is another article about dynamic proxy.
2. Practice
So much said, in plain language, AOP allows us to add and modify code functions without affecting the original code
Before implementing logging, we'll review the order of notifications in Spring Aop (connection points, notifications don't know what it is yet, go to Station B and take a look at the Spring elementary tutorial first).
Add the starter dependency of Aop to the pom file first.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2.1 Definition Notes
Now let's customize a comment so that the method that annotates it will record the request information that calls the method
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented public @interface MyLog { String value() default ""; }
Notes are not the focus of this article. Interesting children's shoes can be searched.
2.2 Face Class
Define our logging facet class, which records the requested information.
@Component @Aspect @Slf4j public class LogAspect { //Start point is custom comment @Pointcut("@annotation(com.example.springaopdemo.demo2.MyLog)") public void MyLog(){} @Before("MyLog()") public void Before(JoinPoint jp){ //Get the HttpServletRequest object ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); assert requestAttributes != null; HttpServletRequest request = requestAttributes.getRequest(); log.info("==========Request Information=========="); log.info("Request Links : {}",request.getRequestURL().toString()); log.info("Http Method : {}",request.getMethod()); log.info("Class Method : {}.{}",jp.getSignature().getDeclaringTypeName(),jp.getSignature().getName()); log.info("Ip : {}",request.getRemoteAddr()); log.info("Args : {}", Arrays.asList(jp.getArgs())); } @Around("MyLog()") public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = proceedingJoinPoint.proceed(); log.info("execution time : {} ms", System.currentTimeMillis() - startTime); log.info("Return parameters : {}", result); return result; } }
With @Around wrapping notifications, we can do simple performance logging, and with Oshi we can even record CPU s, memory usage, before and after executing this method.
Oshi is Java's free JNA-based operating system and hardware repository with Github address: https://github.com/oshi/oshi
It has the advantage of not installing any other native libraries and is designed to provide a cross-platform implementation for retrieving system information such as operating system version, processes, memory and CPU usage, disks and partitions, devices, sensors, and so on.
2.3 Write test methods
Write a simple request that requires a request body of a User object and returns a Map result.
@RestController @Slf4j public class Controller { @PostMapping("/test") @MyLog public Map<String, Object> testAop(@RequestBody User user){ Map<String,Object> map = new HashMap<>(); map.put("code",200); map.put("errorMsg","success"); return map; } }
2.4 Run Results
Use the Http Client that comes with IDEA to test the api
Result:
You can see that by using AOP, we can log requests for information for each method in the Controller without modifying the code in the Controller.
We can also specify whether the tangent class will work in a production or development environment by adding annotations to the tangent class.
@Profile({"dev"})
Then define spring in the configuration file. Profiles. The property of the active is sufficient.
3. Summary
Because after learning Spring, you know that there is AOP, but you never really use it in real projects. These days, when you study logging, you find that AOP is useful in logging. You can even use AOP to encrypt and decrypt parameter data without breaking into your code. However, although AOP is convenient to use, it can not be abused, since the underlying AOP uses dynamic proxies, which must use reflection to modify the method. Reflection can have an impact on performance.
4. Reference Articles
[SpringBoot] AOP Application Instance_ sysu_lluozh-CSDN Blog