Didn't you say you would Aop?

Early in the morning, Xiao Wang hurried to me and said: brother Zhou, I want to ask about the function of logging.

Because a project of the company needs to be connected with other platforms, we need to provide them with a set of interfaces. Yesterday, I assigned Xiao Wang to record the interface log.

The following is my main conversation with Xiao Wang.

Me: what's the matter?

Xiao Wang: I put the function of recording interface logs into each controller. Now it feels a little cumbersome. Is it inappropriate for me to do so?

Me: why log in each interface?

Xiao Wang: at first, I used the interceptor, but such a request recorded two records.

Me: why two?

Xiao Wang: record a request data in the preHandle and a response data in the postHandle.

I:... Didn't you say you would Aop?

Xiao Wang: Aop is the same. A request data is recorded in the pre notification and a response data is recorded in the post notification.

Xiao Wang: this data is different from that used to record the operation log. In the past, only one operation log needs to be recorded in the pre notification, but now there is a response, so the log can only be recorded in the controller.

Me: did you know there was a circular notice? You talk about Aop. There are several types of notifications.

Xiao Wang: there are five kinds in total, namely:

  • Pre notification: run Before we execute the target method (@ Before)
  • Post notification: After the operation of our target method ends, no matter whether there is any exception (@ After)
  • Return notification: run after the normal return value of our target method (@ AfterReturning)
  • Exception notification: run after an exception occurs in our target method (@ AfterThrowing)
  • Surround notification: the call of the target method is determined by the surround notification, that is, you can decide whether to call the target method, joinpoint Procced () is the code that executes the target method. Surround notification can control the return object (@ Around)

Next, let's demonstrate how to use surround notification to solve Xiao Wang's problem.

Step 1: provide an interface to receive parameters and responses

@RestController
public class TestController {
    @GetMapping("/getName")
    public String getName(HttpServletRequest request) throw Exception {

        String result = "Java journey";
        String age = request.getParameter("age");
        if("18".equals(age)){
            result = "Unrecognized";
        }
        return result;
    }
}

Step 2: define the tangent point

execution() is a commonly used expression to define the tangent point. The syntax of execution() is as follows:

execution(Modifier return value package.class.Method name(parameter) throws abnormal)

Of which:

The modifiers throws and throws can be omitted

According to these explanations, we can describe the interface in the first step with execution() expression:

execution(String binzh.website.controller.TestController.GetName(HttpServletRequest))
  • *: match all
  • ..: Match any method parameter
  • .. When it appears in the class name, it must be followed by *, indicating all classes under the package and descendant package;

Now let's optimize the above expression and define all methods that cut into the controller package and all packages under the controller

execution(* binzh.website.controller..*.*(..))

Step 3: log around the notification

@Around("execution(* binzh.website.controller..*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    String age = request.getParameter("age");
    Object proceed = "";
    try {
        proceed = joinPoint.proceed();
    } catch (Throwable e) {
        e.printStackTrace();
    }
    System.out.println("age==="+age);
    System.out.println("proceed ===="+proceed);
    return proceed;
}

The operation results are as follows:

age===19
proceed ====Java journey

The reason why we can use surround notification to deal with Xiao Wang's problem. One of the important reasons is that all the interfaces we provide are uniformly encrypted, and the final requested parameters are a fixed name. It should also be noted that the return value type of the surround notification must be greater than or equal to the return value of the method, that is, add the String type returned by your method, and the surround notification cannot be written as void type.

When Xiao Wang saw this, he suddenly realized that he was ready to go back and have a try. I grabbed him in a hurry.

Me: what if the interface is abnormal?

Xiao Wang: then I can handle it in the exception notice.

Me: think again?

Xiao Wang: it doesn't seem to work. The request parameters can't be obtained in the exception notification.

Me: is it OK to capture and process in the surround notification?

At this time, seeing Xiao Wang's eyes shining, he was surprised and said: the surrounding notice is so awesome that it can complete the work of pre notice, post notice and exception notice!

This article has a lot of plays. Don't be surprised. Actual combat is the most effective way to improve technology!

Tags: Spring Boot AOP

Posted by Emperio on Wed, 25 May 2022 18:24:15 +0300