Talking about the understanding of AOP, simple and easy to understand

1. What is pandas?

AOP: The full name is Aspect Oriented Programming, that is: aspect-oriented programming. Simply put, it is to extract the repeated code of our program, and when it needs to be executed, use the technology of dynamic proxy to enhance our existing method without modifying the source code .
The role of Aop: During the running of the program, the existing method is enhanced without modifying the source code.
Aop advantages: reduce repetitive code, improve development efficiency, and facilitate maintenance
AOP implementation method: use dynamic proxy technology

How to do it first, the principle is combined with the code, so it is easier to understand

2. Use steps

After creating a normal Maven project,

1. Import dependencies

Import dependencies into pom.xml. There is nothing to say in this step, and the import is over.

<dependencies>
    <!--spring坐标-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.9.RELEASE</version>
    </dependency>
    <!--解析切入点表达式-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.0.9.RELEASE</version>
    </dependency>
</dependencies>

2. Add configuration beans.xml configuration file

There are two methods for this step. Here I recommend the second one. I think it is much more convenient. It is a matter of building an ordinary java class and adding three annotations.

1. Use xml configuration

Enable annotation scanning and generate aspect proxy objects

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启自动扫描注解-->
    <context:component-scan base-package="demo"/>

    <!--开启AspectJ生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

2. The way to use the configuration class

package demo;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration //设置为配置文件
@ComponentScan({"demo"}) //组件扫描
@EnableAspectJAutoProxy //开启生成切面的代理对象
public class SpringConfig {
}

Step 3: Add a business class Service

Here is to simply create an ordinary java class, and then write your own method, remember to add that @Service, that's it

package demo;

import org.springframework.stereotype.Service;

@Service
public class AccountService {

    public void saveAccount(){
//        int a = 10/0;
        System.out.println("执行了添加的操作");
    }

    public void deleteAccount(){
        System.out.println("执行了删除的操作");
    }

    public void updateAccount(){
        System.out.println("执行了修改的操作");
    }

}

Step 4: Add an aspect class

The main thing to pay attention to here is this sentence

* demo.MyService.*(..)

This sentence is to locate all the methods under MyService under the demo document, and then we look at the @Before, we first define where the cut point is, and before the cut point, it can be executed before the cut point. This is The most important thing about this AOP. There are a total of 5 methods here, and I will place them in the second code block specifically.

@Before: The notification method will be executed before the target method is called
@After: The notification method will be called after the target method returns or an exception
@AfterReturning: The notification method will be called after the target method returns
@AfterThrowing: The notification method will throw an exception in the target method After calling
@Around: the notification method will encapsulate the target method

/**
 * 切面类(增强类),对AccountService的方法进行增强
 */
@Component
@Aspect//表示这是一个切面类,增强类
public class MyAspect {
    //告诉程序,需要对那一个类的哪一个方法进行增强
    @Pointcut("execution(* demo.MyService.*(..))")
    public void pott(){}

    @Before("pott()")
    public void beforeEat(){
        System.out.println("大乱斗");
    }
}
@Pointcut("execution(* demo.*.*(..))")//设置切入点表达式
private void pott(){}

/**
 * 前置通知
 * 应用场景:权限控制(权限不足抛出异常)、记录方法调用信息日志
 */
@Before("pott()")
public void beforePrintLog(){
    System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志******");
}

/**
 * 后置通知,在异常时不执行
 * 特点:在目标方法运行后返回值后再增强代码逻辑
 * 应用:与业务相关的,如银行在存取款结束后的发送短信消息
 */
@AfterReturning("pott()")
public void afterReturningPrintLog() {
    System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志=========");
}

/**
 * 异常通知
 * 作用:目标代码出现异常,通知执行。记录异常日志、通知管理员(短信、邮件)
 * 应用场景:处理异常(一般不可预知),记录日志
 */
@AfterThrowing("pott()")
public void afterThrowingPrintLog() {
    System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志++++++++++++");
}

/**
 * 最终通知,不管异常与否
 * 作用:不管目标方法是否发生异常,最终通知都会执行(类似于finally代码功能)
 * 应用场景:释放资源 (关闭文件、 关闭数据库连接、 网络连接、 释放内存对象 )
 */
@After("pott()")
public void afterPrintLog() {
    System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志&&&&&&&&&&&&&&&&&&");
}

/**
 * 环绕通知
 * 特点:目标方法执行前后,都进行增强(控制目标方法执行)
 * 应用:日志、缓存、权限、性能监控、事务管理
 */
@Around("pott()")
public Object aroundPrintLog(ProceedingJoinPoint point){
    //定义返回值
    Object result = null;
    try {
        //获得切入点中方法的参数列表
        Object[] args = point.getArgs();
        //调用前置通知
        beforePrintLog();
        //执行切入点的方法
        result = point.proceed(args);
        //调用后置通知
        afterReturningPrintLog();
    } catch (Exception e){
        //调用异常通知
        afterThrowingPrintLog();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    return result;
}

Step 5: Define test class for testing

Finally test it

package demo;

import javafx.application.Application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        //使用xml方式配置spring
//        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //使用配置类的方式配置spring
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        AccountService accountService = (AccountService) context.getBean("accountService");
        accountService.saveAccount();
//        accountService.deleteAccount();
//        accountService.updateAccount();
    }
}

Guess you like

Origin blog.csdn.net/qq_42176665/article/details/128006114