Two common methods of locating tangent points in SpringBoot

Sometimes, we use AOP to enhance the aspect. When writing aspect classes, we need to locate the method to try the aspect for enhancement. This article mainly explains two methods to locate the pointcut in SpringBoot, one is to use execution expression, and the other is to use custom annotation.

Next, a simple example is given to explain the use of these two methods.

<==========Before method execution==========>
method();
<==========After method execution==========>

execution expression

The method of execution expression is mainly to select the method to be enhanced by expression when defining the tangent point.

Interpretation of execution expression

execution(<Modifier mode>?<Return type mode><Method name pattern>(<Parameter mode>)<Abnormal mode>?)

// Matches all methods in the specified package
execution(* com.luke.service.*(..))

// Match all public methods in the current package
execution(public * UserService.*(..))

// Matches all public methods in the specified package, and the return value is a method of type int
execution(public int com.luke.service.*(..))

// Matches all public methods in the specified package, and the first parameter is String, and the return value is a method of type int
execution(public int com.luke.service.*(String name, ..))

Custom cut class:

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.luke.springdata.controller.*.*(..))")
    public void operationLog(){}

    /**
     * Only one enhancement of Around is defined here for display
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object proceed = null;
        try {
            System.out.println("Before method execution");
            proceed = joinPoint.proceed();
            System.out.println("After method execution");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}

The execution expression for this pointcut is
All methods in the com.luke.springdata.controller package.

Use the @ Around annotation to indicate the enhanced method and specify the tangent point.

Controller class for test

@RestController
@RequestMapping("/person")
public class PersonController {

    @GetMapping("/test")
    public void test(){
        System.out.println("Method is executed");
    }
    
}

Run the project, call the method, and view the results.

Before method execution
 Method is executed
 After method execution

How to customize annotations

The way to customize annotations is to add custom annotations to the methods that need to be enhanced.

Custom annotation class:

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log{
    
}

Here, an annotation Log is customized, which can only be added to methods.

Custom cut class:

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.luke.springdata.annotation.Log)")
    public void operationLog(){}

    /**
     * Only one enhancement of Around is defined here for display
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object proceed = null;
        try {
            System.out.println("Before method execution");
            proceed = joinPoint.proceed();
            System.out.println("After method execution");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}

The custom facet class written here defines a facet with @ Pointcut annotation, and this time @ annotation(xxx) is used to indicate which method has added XXX annotation, and the facet will be used for enhancement.

At the same time, use this section on each enhanced method, and then write normal method enhancement logic.

Controller class for test

@RestController
@RequestMapping("/person")
public class PersonController {

    @Log
    @GetMapping("/test")
    public void test(){
        System.out.println("Method is executed");
    }
    
}

At this time, add @ Log annotation to the method that needs to use the section, call the method and view the effect.

Before method execution
 Method is executed
 After method execution

summary

Both methods can realize the function of AOP. In use, if all methods under a package need to be enhanced in this aspect, it is more convenient to use execution expression. However, if only some methods are needed and distributed in different classes, the annotation method is more flexible.

Posted by Kilo on Sun, 28 Nov 2021 00:17:04 -0800