Spring Series (8) --- Detailed description of SpringAOP--related concepts and basic operations of aspect-oriented programming

AOP is actually a unified process for a certain class or a certain function in the program, such as performing some verification operations between the front and back ends for the login function, and verifying whether the user name or password is correct.

♞ Related concepts

  • Aspect: AOP is mainly for the operation or definition of a certain function, and this function is called an aspect, such as the user login function, which is an aspect;
  • Pointcut: pointcut is a method in the aspect, or a rule that defines AOP interception; if the aspect is a database, then the pointcut is a table in the database;
  • Connection point: All possible triggers of AOP can be called connection points; it is mainly used to match multiple points in the cut plane. If the cut point is a table, then the connection point is equivalent to a row of data in the table;
  • Notification: Specifies the timing and method of AOP execution.

For example: to verify the user's login function, this user function is an aspect, and the verification of user login may need to be verified on multiple pages, then these multiple pages are equivalent to connection points; when calling the user's login verification method, the entire verification method is a cut point, and the method body is the notification.
insert image description here

♞♞ Specific operation steps

The first step: add SpringAOP dependency;

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.7.4</version>
        </dependency>

Step 2: Add facets and points;

@Aspect  // 当前是一个切面
@Component
public class UserAspect {
    
    
    // 设置拦截规则, Pointcut 就是一个切点
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
    
    
    }
}

* means that all methods in UserController must be intercepted, and the following * (…) means that interception conditions can be added, such as (String, Integer) means that only methods of type (String, Integer) in UserController are intercepted.


Step 3: Define notification Advice, describe the timing of interception execution and specific method implementation;

@Aspect  // 当前是一个切面
@Component
public class UserAspect {
    
    
    // 设置拦截规则
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
    
    
    }

    /**
     * 定义 pointcut 切点的前置通知
     * 在执行目标方法之前执行的方法就是前置通知
     */
    @Before("pointcut()")
    public void doBefore() {
    
    
        System.out.println("前置通知: 执行了前置通知!");
    }

    /**
     * 针对 pointcut 切点的后置通知
     */
    @After("pointcut()")
    public void doAfter() {
    
    
        System.out.println("后置通知: 执行了后置通知!");
    }

    /**
     * AfterReturning
     * 在后置通知之前执行的
     */
    @AfterReturning("pointcut()")
    public void doAfterReturning() {
    
    
        System.out.println("执行了 AfterReturning 方法!");
    }

    /**
     * AfterThrowing: 目标方法抛出异常后调用
     * 只有报了异常之后才会执行, 执行在 方法之后,
     * 执行了 AfterThrowing 后, 将不会执行 AfterReturning
     */
    @AfterThrowing("pointcut()")
    public void doAfterThrowing() {
    
    
        System.out.println("执行了 AfterThrowing 方法!");
    }

    /**
     * 环绕通知(将所有通知和方法全部包围起来了)
     */
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
    
    
        // Spring 中的时间统计对象
        StopWatch stopWatch = new StopWatch();
        Object result = null;
        System.out.println("环绕通知: 前置方法!");
        try {
    
    
            stopWatch.start(); // 统计方法的执行时间: 开启计时
            // 执行目标方法, 以及目标方法所对应的相应的通知
            result = joinPoint.proceed();
            stopWatch.stop(); // 统计方法的执行时间: 停止计时
        } catch (Throwable e) {
    
    
            e.printStackTrace();
        }
        System.out.println("环绕通知: 后置方法!");
        System.out.println(joinPoint.getSignature().getName() + " 方法执行花费的时间: " +
                stopWatch.getTotalTimeMillis() + "ms");
        return result;
    }
}

♞♞♞ About AspectJ Expressions

insert image description here
like:

  • execution(* com.example.demo.User.*(. .)) : match all methods under the User class;
  • execution(* com.example.demo.User+.*(. .)) : match the subclasses of this class and all methods of this class;
  • execution(* com.example.* .*(. .)) : match all methods of all classes under com.example package;
  • execution(* com.example. .* .*(. .)) : Match all methods of all classes under the com.example package and all descendant packages;
  • execution(* addUser(String, int)) : Match the addUser method, and the first parameter type is String, and the second parameter type is int.

Guess you like

Origin blog.csdn.net/Onion_521257/article/details/129901276