Understand AOP in one article, easy to understand


foreword

提示:这里可以添加本文要记录的大概内容:

Spring has two cores, AOP and IOC. This article focuses on AOP.


1. What is AOP?

AOP is Aspect Oriented Programming, that is, aspect-oriented programming.
What is aspect-oriented?
To understand the concept of AOP, let's use OOP as an example. Everyone knows OOP, object-oriented programming. For example, a business component BookService has several business methods:

  • createBook: add a new Book;
  • updateBook: modify Book;
  • deleteBook: delete Book.

For each business method, for example, createBook(), in addition to business logic, security checks, logging and transaction processing are required, and its code looks like this:

public class BookService {
    
    
    public void createBook(Book book) {
    
    
        securityCheck();
        Transaction tx = startTransaction();
        try {
    
    
            // 核心业务逻辑
            tx.commit();
        } catch (RuntimeException e) {
    
    
            tx.rollback();
            throw e;
        }
        log("created book: " + book);
    }
}

Then you will find that the method of addition, deletion and modification needs to make these judgments, which is very cumbersome. There are two solutions:
one feasible way is to use the Proxy mode to put a certain function, such as permission checking, into the Proxy, but The disadvantage of this method is that it is cumbersome. The interface must be extracted first, and then Proxy must be implemented for each method.
So the second method AOP came into being.
AOP technology looks mysterious, but in fact, it is essentially a dynamic proxy, which allows us to separate some common functions such as permission check, log, transaction, etc. from each business method.

2. Use steps

1. Introduce Aspect dependency

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${
    
    spring.version}</version>
</dependency>

2. Write code

Here I will first simulate a simple scene and teach you with the most concise code.
Suppose we update a piece of data and need to record a log. If an error needs to be thrown, we can use pre-notification (in fact, post-notification after successful insertion) and exception notification

2.1 Use annotation + AOP to realize aspect

First we define an annotation class AdminOnly

@Retention(RetentionPolicy.RUNTIME)  //运行期
@Target(ElementType.METHOD) //作用在方法上
public @interface AdminOnly {
    
    
}

Then you can write the aspect class,

@Aspect
@Component
public class CheckUserAspect {
    
    

    //注解方式,方法其实是个空壳
    //此时注解就跟此方法绑定了,后续使用注解的方法都会被带上切面所标识的方法
    @Pointcut("@annotation(com.tao.aop.annotation.AdminOnly)")
    private void checkAdmin(){
    
    

    }


    @Before("checkAdmin()") // 前置通知,checkAdmin()跟拦截器进行绑定
    private void Before(){
    
    
        System.out.println("前置通知...日志记录");
    }

    @AfterThrowing( value = "checkAdmin()",throwing = "e")  //异常通知 checkAdmin()跟拦截器进行绑定
    private void afterThrowing(Throwable e) {
    
    
        System.out.println("报错后通知...");
        System.out.println(e.getMessage());
    }
}

UserService class

@Service
public class UserService {
    
    

    @AdminOnly  //注:要想被切面的方法需要加上这个注解
    public void update() {
    
    
        System.out.println("进行了update操作...");
    }
}

At this time, use the test class and call the update method in UserService, and you will find that the result is:

Pre-notification...Permission verification
performed an update operation...

AOP operations have been added. Next, I will explain how to define the scope through execution

2.2 Use execution+AOP to implement aspects

The aspect class CheckUserAspect, it can be seen that I have intercepted all the classes and methods under the service package

@Aspect
@Component
public class CheckUserAspect {
    
    

 //表达式方式
    // execution 代表的意思
    /*
    * 第一个 * 号代表返回值为任意类型
    *第二位代表 包名
    *第三位 .* 代表任意类
    *第四位 .*(..) 表示任何方法名的任何参数
    *
    * */
    @Pointcut("execution(* com.tao.aop.service.*.*(..))")
    private void checkAdmin(){
    
    
        //此方法是空壳
    }


    @Before("checkAdmin()") // 前置通知,checkAdmin()跟拦截器进行绑定
    private void Before(){
    
    
        System.out.println("前置通知...日志记录");
    }

    @AfterThrowing( value = "checkAdmin()",throwing = "e")  //异常通知 checkAdmin()跟拦截器进行绑定
    private void afterThrowing(Throwable e) {
    
    
        System.out.println("报错后通知...");
        System.out.println(e.getMessage());
    }
}

UserService1 class

@Service
public class UserService1 {
    
    


    public void update() throws Exception {
    
    

        System.out.println("进行了update操作...");
        throw new  Exception("自造异常");
    }
}

Both the pre-notification and the exception notification I simulated are triggered, and the results are as follows:

Pre-notification...permission verification,
update operation...
notification after error reporting...
self-made exception

3. Write at the end

There are also some types of interception notifications, I will not give examples one by one, interested students can follow the official account, discuss and ask questions.

@Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;

@After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;

@AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;

@AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;

@Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。

Summarize

In general, AOP is already a must-have for development or must be asked in interviews. It is a commonplace question. If you want detailed source code or don’t understand it, pay attention to it.No public,replyAOP example source codeYou can get all the source code

If you have questions about Java (not limited to the questions in this article), welcome to ask your questions on the official account, and I will answer them for you as soon as possible~

insert image description here

There is a surprise~
insert image description here

Guess you like

Origin blog.csdn.net/qq_42429369/article/details/125146530