一文带你迅速了解下Spring中的AOP

本文介绍了AOP(面向切面编程)的概念及其在Spring框架中的应用,包括切面、切点、通知的不同类型,以及SpringAOP的实现过程,涉及JDKProxy和CGLIB的区别。
摘要由CSDN通过智能技术生成

1. 什么是AOP?

AOP(Aspect Oriented Programming):面向切面编程。
面向切面编程是一种思想,其实就是对某一类事情进行统一的处理。而 SpringAOP就是一种AOP的具体实现的框架。这就好比 IOC 和 DI 一样的关系。
在这里插入图片描述
上述就是对登录功能进行了一个统一的处理!

2. AOP能用来干些什么?

除了上面的判断登录之外,还有:

  • 统一日志记录
  • 统一的方法执行时间统计
  • 统一的返回格式设置
  • 统一的异常处理
  • 事务的开启和提交

3. 学习AOP

3.1 AOP的组成

3.1.1 切面(Aspect)

切面:定义的是事件,也就是AOP是用来做啥的。
例如:用来做用户登录校验

3.1.2 切点(Pointcut)

切点:定义具体拦截规则。
例如:哪些接口需要判断用户登录,哪些不需要

3.1.3 通知(Advice)

通知:定义AOP具体的执行方法。
例如:从 Session 中获取用户信息,如果获取到则是登录,没获取到表示未登录。

3.1.4 连接点(Jion Point)

连接点:有可能触发切点的所有点,也就是所有接口。

3.2 SpringAOP实现

3.2.1 添加依赖

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

3.2.2 定义切面

@Aspect  // 表示这个为切面
@Component 
public class UserAspect {
}

上述中,@Aspect注解表示这个类为切面类。@Component表示这个类随着SpringBoot启动而启动。

3.2.3 定义切点

@Aspect  // 表示这个为切面
@Component
public class UserAspect {

    // 定义切点
    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
    public void pointcut(){}
}

使用@Pointcut注解进行定义切点,格式为 :
excution(<修饰符><返回类型><包.类.⽅法(参数)><异常>) ,一般修饰符和异常可省略。

3.2.4 执行通知

@Aspect  // 表示这个为切面
@Component
public class UserAspect {

    // 定义切点
    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
    public void pointcut(){}

    // 前置通知
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("执行了前置通知");
    }

    // 后置通知
    @After("pointcut()")
    public void doAfter(){
        System.out.println("执行了后置通知");
    }

    // 返回之后通知
    @AfterReturning(value = "pointcut()",returning = "")
    public void doAfterReturning(){
        System.out.println("执行了返回之后通知");
    }

    // 异常通知
    @AfterThrowing("pointcut()")
    public void doAfterThrowing(){
        System.out.println("执行了异常通知");
    }
    // 环绕通知
    @Around("pointcut()")
    public Object doAroud(ProceedingJoinPoint joinPoint){
        Object result = null;
        System.out.println("环绕通知执行之前");
        try {
            // 执行目标方法
            result = joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        System.out.println("环绕通知执行之后");
        return result;
    }
}

可以通过下面看到执行顺序:
在这里插入图片描述

4. SpringAOP实现原理

SpringAOP是构建在动态代理的基础上实现的,因此 Spring 对 AOP 支持局限于方法级别上。

  • JDK Proxy:默认情况下,实现了接口的类,使用 AOP 基于 JDK 生成代理类
  • CGLIB:默认情况下,没有实现接口的类,通过实现代理类的子类来实现动态代理(被final修饰的类不能代理)
  • 两者底层都是通过反射

JDK 和 CGLIB 区别:

  • JDK来自JAVA;CGLIB属于三方
  • JDK:是通过实现类接口的类来生成代理类;CGLIB是通过实现了代理类的子类来实现动态地理
  • JDK7之后版本,JDK Proxy性能高于 CGLIB;JDK7之前,CGLIB 性能远远高于 JDK Proxy
  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个想打拳的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值