Spring AOP:一篇文章让你掌握它

目录

一、什么是AOP?Spring AOP?

AOP的功能:

适合使用AOP的情况:

二、AOP的组成

切面(Aspect)

切点(Pointcut)

通知(Advice)

连接点(Join Point)

三、Spring AOP的使用

使用步骤

切点拦截表达式的创建

四、Spring AOP实现原理

了解什么是 织入 ?

动态代理


 

一、什么是AOP?Spring AOP?

和IOC DI一样,AOP只是一种思想,而Spring AOP是一个框架,是AOP思想的实现。

AOP(Aspect Oriented Programming):面向切面编程,它是一种思想,它是对某一类事情的集中处理。比如用户登录权限的效验,没学 AOP 之前,我们所有需要判断用户登录的页面(中的方法),都要各自实现或调用用户验证的方法,然而有了 AOP 之后,我们只需要在某处配置一下,所有需要判断用户登录页面(中的方法)就全部可以实现用户登录验证了,不再需要每个方法中都写相同的用户登录验证了。这样不仅简化了代码,而且实现更加方便。

AOP的功能:

除了统一的用户登录判断之外,AOP 还可以实现:

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

适合使用AOP的情况:

对于功能统一,且使用的地方较多的功能,就可以考虑 AOP来统一处理了。

也就是说使用 AOP 可以扩充多个对象的某个能力,所以 AOP 可以说是 OOP(Object Oriented
Programming,面向对象编程)的补充和完善。

 

二、AOP的组成

切面(Aspect)

  • 通俗点讲就是 处理某方面具体问题的一个类里面包含了很多的方法,这些方法就是切点和通知。

切点(Pointcut)

用来进行主动拦截的规则(配置)

通知(Advice)

  • 前置通知@Before:通知方法会在目标方法调用前执行
  • 后置通知@After:通知方法会在目标方法返回或者抛出异常后调用
  • 返回之后通知@AfterReturning:通知方法会在目标方法返回后调用
  • 抛异常后通知@AfterThrowing:通知方法会在目标方法抛出异常后通知
  • 环绕通知@Around:通知包裹了被通知的方法,在被通知的方法,通知之前和调用之后执行的自定义行为

连接点(Join Point)

  • 可能会触发AOP的规则的所有点(请求)

 

 

 

三、Spring AOP的使用

我们大概知道了Spring AOP是干嘛的了,那这个怎么使用呢

使用步骤

①添加的依赖

  • 在Spring Boot添加的时候没有直接的AOP,要我们在pom.xml中手动添加。
  • 自己找依赖的方法:中央仓库,搜索spring aop,寻找 Spring Boot Starer AOP进去,选择 与 SpringBoot 版本一致的。
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

②定义切面(创建切面类)③定义切点(配置拦截规则)④定义通知的实现

package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component //随着框架的启动而启动
@Aspect //告诉框架我是一个切面类
public class UserAspect {

    //切点(配置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*())")
    public void pointcut() {
    }

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

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

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object obj = null;
        System.out.println("--Around方法开始执行");
        try {
            // 执行拦截方法
            obj = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("--Around方法执行结束");
        return obj;
    }
}


//打印结果
--Around方法开始执行
beforeAdvice:执行了前置通知
执行了UserController里的内容
afterAdvice:执行了后置通知
--Around方法执行结束

切点拦截表达式的创建

  • 修饰符(一般可省略)
    •  public        公共方法
    •  *                 任意
  • 返回值(不能省略)
    •  void         没有返回值
    •  String      返回字符串类型
    •  com.gyf.crm                        固定包
    •  com.gyf.crm..                      crm包下的所有包(包含自身)
    •  com.gyf.crm.*.service        crm下子包任意(例如:com.gyf.crm.user.service)
    •  com.gyf.crm.*.service..      crm下子包任意,固定目录seivice,service目录任意包
    •  UserService          指定类
    •  *Service                以Service结尾的类
    •  User*                     以User开头的类
    •  *                             任意
  • 方法名(不能省略)
    •  addUser         固定方法
    •  add*               以add开头的方法
    •  *User             以User结尾的方法
    •  *                     任意方法
  • 参数
    • ()                  无参
    • (int)              有一个int的参数
    • (int,String)有一个int和一个String的参数
    • (..)                参数任意
  • throws(可以省略一般不写)

 案例:

  • execution(* com.cad.demo.User.*(..))           匹配 User 类里的所有方法
  • execution(* com.cad.demo.User+.*(..))        匹配该类的 类包括该类的所有方法
  • execution(* com.cad.*.*(..))         匹配 com.cad 包下的所有类的所有方法
  • execution(* com.cad..*.*(..))        匹配 com.cad 包下、 孙包下所有类的所有方法
  • execution(* addUser(String, int))        匹配 addUser 法,且参数为String和int

 

 

 

四、Spring AOP实现原理

了解什么是 织入 ?

织入 是把 切面 应用到 目标对象,并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期可以有多个点进行织入:

  • 编译器:切面在目标类编译时被织入
  • 类加载期:切面在目标类加载到JVM时被织入
  • 运行期:切面在应用运行的某一时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象。SpringAOP就是以这种方式织入切面的。

动态代理

我们学习的AOP主要基于两种方式(JDK和CGLIB),在运行期间织入字节码,生成代理类。这两种方法都采用了反射

  • JDK:是Spring框架的默认方式
  • CGLIB:是Spring Boot框架的默认方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

shn!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值