[JavaEE Advanced] - Section 7. Spring AOP Unified Function Processing (Aspect, Point Cut, Join Point, Notification)

About the author: Hello everyone, I am Weiyang;

Blog Homepage: Weiyang.303

Series column: Advanced JavaEE

Daily sentence: There is only one time in a person's life to make a difference, and that is now! ! !

Article directory

foreword

1. Pre-knowledge of AOP

1.1 What is AOP

1.2 The role of AOP 

2. Implementation of Spring AOP

2.1 Add Spring AOP framework support

2.2 Define aspect (Aspect)

2.3 Define Pointcut

2.4 Define Advice (Advice)

3. Example display (timer)

Code 

Summarize



 

foreword

Today we will cover about Spring AOP unified function processing


1. Pre-knowledge of AOP

1.1 What is AOP

Aop is an idea to deal with a certain problem in a unified way, such as verifying whether a user is logged in or not .

Verify that the user is logged in Instance analysis:

When using Aop, each class (page) we need to verify has a call verification method, and after using Aop, we only need to configure the verification rules somewhere, and then we can realize the class that needs verification. Login verification, no need to repeatedly call the verification method for each class.

Aop consists of aspects, points, joins, and notifications;

section:

The aspect represents the function (class) that we want to deal with uniformly - such as verifying whether the user is logged in;

Cut-off point:

The cutting point is the rule of whether to perform Aop interception (which pages do not require login verification and which ones do, such rules)

Junction:

The connection point is specific to which pages need to be intercepted (which classes need to call the login verification method)

notify:

Notification is the implementation of the specific method to verify whether the user is logged in (code details)——"pre-notification, post-notification;

And AOP is a kind of thought, and SpringAOP is the realization of AOP thought by this framework (similar to IoC and DI)  ;


1.2 The role of AOP 

AOP consists of the following four parts:

  1. Aspect: Define the AOP business type (indicating what the current AOP does).
  2. Connection point (Join Point): The place where it is possible to call AOP is called a connection point.
  3. Pointcut: Define AOP interception rules.
  4. Advice (Advice) [enhancement method]: Define when to do something (code implementation details, sequence).

Advice:

It defines the specific business to be executed by the intercepted method, such as the user login authority verification method is the specific business to be executed.

Classification of notifications:

  • a) Pre-notification: notification (event) executed before the intercepted target method
  • b) Post notification: Notification (event) executed after the intercepted target method
  • c) Notify after return: Notify after the intercepted target method returns data
  • d) Notification after an exception is thrown: a notification that is executed after the intercepted target method throws an exception
  • e) Surrounding advice: Advice that is executed before and after the execution of the intercepted method.

The concept of the entire component of AOP is shown in the figure below, taking multiple pages to access user login permissions as an example:


2. Implementation of Spring AOP

2.1 Add Spring AOP framework support

Add support in our project's pom.xml

At this time, we need to use the central warehouse https://mvnrepository.com/ 

Note:
The Spring AOP framework cannot be searched when creating a new project.
In the Spring Boot project, is there a built-in AOP framework?

At this time, we need to use the central warehouse https://mvnrepository.com/ 

 Expansion of details: The version number tag that Spring AOP depends on can be omitted.
Although Spring AOP is not used as a common framework, when we introduce the framework, we need to use the Maven central warehouse to introduce it.
but! In Spring Boot, there are actually records related to the version of Spring AOP,
which can automatically introduce the appropriate version of Spring AOP according to the current project environment.


2.2 Define aspect (Aspect)

Define method steps:



2.3 Define Pointcut

Among them, the pointcut method is an empty method, which does not require a method body. This method name serves as an "identification" to identify which pointcut the following notification method specifically refers to. 

The grammatical composition of a pointcut:

 AspectJ supports three kinds of wildcards:

  • *: match any character, only one element (package, class, or method, method parameter)
  • ..: Match any character, can match multiple elements, must be used in conjunction with * when representing a class
  • +: Indicates that all classes of the specified class are matched according to the type, and must be followed by the class name, such as com.cad.Car+, which means that all subclasses inheriting the class include itself;

Examples of expressions are as follows:

  • execution(* com.example.demo.UserController. *(..)): matches all methods in the UserController class.
  • execution(* com.example.demo.UserController+.*(..)): matches subclasses of the UserController class including all methods of this class
  • execution(* com.example.demo.*.*(..)): matches all methods of all classes under com.example.demo package
  • execution(* com.example.demo..*.*(..)): Match all methods of all classes under the com.example.demo package and descendants package
  • execution(* addUser(String,int)): matches the addUser method, and the first parameter type is String, and the second parameter type is int

2.4 Define Advice (Advice)

The relationship between pointcut and notification:

In the Spring aspect class, the following annotations can be used on the method to set the method as a notification method, and the method will be notified to call after the conditions are met:

  • Use @Before for pre-notification: the notification method will be executed before the target method is called.
  • Post-notification uses @After: the notification method will be called after the target method returns or throws an exception.
  • Use @AfterReturning to notify after returning: the notification method will be called after the target method returns.
  • Use @AfterThrowing to notify after an exception is thrown: the notification method will be called after the target method throws an exception.
  • Surround advice uses @Around:Advice to wrap the method (join point in the collection) to perform custom behavior before and after the notified method receives the notification.

Implement the notification method: when to execute which method.

Take the pre-method as an example to demonstrate:


3. Example display (timer)

We can add a line of code to its value method to record the start time.
Then, record the end time in the post method.
Finally, by subtracting the two, you can get the execution time of the intercepted method!
Do it, right? is not right.

It depends.

If it is in a single-threaded environment (at the same time, only one thread is accessing the method), using the above method, there is no problem.

but!
In the case of multi-threading, there are methods that multiple user accesses will be intercepted, and each access will call the pre-method.
This will causeaccess time  is finally recorded .
The post method is the same.



That is to say, the situation of our final subtraction:
which start time minus which end time, we have no way of knowing!
Moreover, there are very many results, and the number depends on how many threads are accessed.

So, here comes the problem!
Didn't I say earlier: AOP can unify the statistics of method execution time.
However, we have encountered a problem,
so what should we do?

.Some people may say: This is a thread safety issue, add a lock!
Sorry, no! This is the overall problem, and you can't solve the problem even if you add a lock.
but! Aren't we left with a surround notification?
The solution is here.

Next, let's take a look at surround notifications.


Surround advice uses @Around: advice to wrap the notified method, and perform custom behavior before and after the method is notified.

Around notifications @Around:

Visually speaking: Surrounding the notification is to wrap the entire connection point (method), then we can "do whatever we want".

For example:
the method we execute is executed in the current notification, so we can record the start time and end time for each method.

Because every time the target method (join point) and notification are executed, they are together. It feels like it has the atomicity of the transaction;

Code 

 LoginAop code:

package com.example.demo.aop;
 
import com.sun.corba.se.impl.ior.OldJIDLObjectKeyTemplate;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
 
// 切面表示我们要统一出来的问题——比如验证用户是否登录(LoginAop类)
// 切点则是是否进行Aop拦截的规则(哪些页面不需要进行登录验证,哪些需要,这种规则)
// 连接点则是具体到哪些页面需要进行拦截(登录验证)
// 通知则是验证用户是否登录的那个具体方法实现(代码细节)——》前置通知,后置通知
// 验证当前是否登录 的aop实现类
@Component
@Aspect // 表示当前类是一个切面
public class LoginAop {
    // 定义切点
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() { // 标记切点
    }
    // 前置通知
    @Before("pointcut()") // 参数说明这个前置方法是针对与那个切点的
    public void doBefore() {
        System.out.println("前置通知");
    }
    // 后置通知
    @After("pointcut()")
    public void doAfter() {
        System.out.println("后置通知");
    }
    // 环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        StopWatch stopWatch = new StopWatch();
 
        Object o =  null;
        System.out.println("环绕通知开始执行");
        try {
            stopWatch.start();
            o = joinPoint.proceed();
            stopWatch.stop();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("环绕通知结束执行");
        System.out.println("执行花费的时间: " + stopWatch.getTotalTimeMillis() + "ms");
        return o;
    }
}

Summarize

 

Guess you like

Origin blog.csdn.net/qq_64861334/article/details/130324205