《B站-Spring源码解析》学习笔记(五)——AOP功能测试

视频地址:https://www.bilibili.com/video/BV1oW41167AV
对应代码Git库地址:https://github.com/whh306318848/spring-annotation.git

  1. AOP【动态代理】:指在程序运行期间,动态的将某段代码切入到指定方法指定位置进行运行的变成方式
  2. 使用AOP步骤:
    2.1. 在pom文件中导入AOP模块,String AOP模块做了一些简化,只需要配置几个注解就可以运行起来
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.12.RELEASE</version>
</dependency>

2.2. 定义业务逻辑类MathCalculator,在业务逻辑运行的时候将日志进行打印(方法运行之前、方法运行结束、方法出现异常等情况)

public class MathCalculator {

    public int div(int i, int j) {
        return i / j;
    }
}

2.3. 定义一个日志切面类LogAspects,切面类里面的方法需要动态感知MathCalculator.div运行到哪里进行执行

public class LogAspects {
    public void logStart() {
        System.out.println("除法运行...参数列表是:{}");
    }

    public void logEnd() {
        System.out.println("除法结束...");
    }

    public void logReturn() {
        System.out.println("除法正常返回...运行结果:{}");
    }

    public void logException() {
        System.out.println("除法异常...异常信息:{}");
    }
}

通知方法类型:
- 前置通知(@Before):相当于logStart,在目标方法运行之前运行
- 后置通知(@After):相当于logEnd,在目标方法运行结束之后运行(无论方法正常结束还是异常结束都调用)
- 返回通知(@AfterReturning):相当于logReturn,在目标方法正常返回之后运行
- 异常通知(@AfterThrowing):相当于logException,在目标方法运行出现异常以后运行
- 环绕通知(@Around):其是一个动态代理,可以手动推进目标方法运行(joinPoint.proceed()),是最底层的通知

2.4. 给切面类的目标方法标注何时何地运行(标志通知注解)

public class LogAspects {

    // 抽取公共的切入点表达式
    // 1、如果是本类引用,则@Pointcut的值不写任何内容
    // 2、其他的切面引用,则@Pointcut要写execution(切入点表达式,即指定在哪个方法切入)
    @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
    public void pointCut() {}

    // @Before注解是指在目标方法之前切入,其值是切入点表达式(指定在哪个方法切入)
    @Before("public int com.atguigu.aop.MathCalculator.*(..)")
    public void logStart() {
        System.out.println("除法运行...参数列表是:{}");
    }

    // @After注解是指在目标方法运行结束之后切入
    @After("pointCut()")
    public void logEnd() {
        System.out.println("除法结束...");
    }

    // @AfterReturning注解是指在目标方法正常返回之后切入
    @AfterReturning("pointCut()")
    public void logReturn() {
        System.out.println("除法正常返回...运行结果:{}");
    }

    // @AfterThrowing注解是指在目标方法出现异常之后切入
    @AfterThrowing("pointCut()")
    public void logException() {
        System.out.println("除法异常...异常信息:{}");
    }
}

2.5. 将切面类和业务逻辑类(目标方法所在类)都加入到容器中

@Configuration
public class MainConfigOfAOP {

    // 将业务逻辑类加入容器中
    @Bean
    public MathCalculator mathCalculator() {
        return new MathCalculator();
    }

    // 将切面类加入容器中
    @Bean
    public LogAspects logAspects() {
        return new LogAspects();
    }
}

2.6. 必须告诉Sring哪个类是切面类,给切面类上加上@Aspect注解

@Aspect
public class LogAspects {
    // ...
}

2.7. 给配置类上加@EnableAspectJAutoProxy注解,开启基于注解的AOP模式

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
    // ...
}

若是使用xml配置文件,则需要在xml配置文件中写入以下代码

<!--    开启基于版的切面功能-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.8. 若想在使用Bean时触发AOP,不能使用自己在代码中创建的对象,需要使用Spring让其中的组件才能触发
2.9. 使用Spring AOP最重要三步总结:
- 将业务逻辑组件和切面类都加入到容器中,并告诉Spring哪个是切面类(@Aspect注解)
- 在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
- 开启基于注解的AOP模式(@EnableAspectJAutoProxy注解)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用 Akismet 来减少垃圾评论。了解我们如何处理您的评论数据