Spring AOP 快速入门

这篇具有很好参考价值的文章主要介绍了Spring AOP 快速入门。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 什么是Spring AOP

AOP(Aspect Oriented Programming): 面向切面编程 , 它是一种思想 , 提供了一种基于切面编程的方式来对应用程序进行模块化和横向切割的方法 , 是对某一类事情的集中处理.

例如用户登录权限的效验 , 没学 AOP 之前 , 我们所有需要判断用户登录页面的方法 , 都要各自实现或调用用户验证的方法 , 这样会导致代码冗余维护成本高 , 而使用 Spring AOP 之后 , 我们只需定义一个切面 , 通过在切面中编写代码实现用户的登录验证 , 具体实现步骤是在切面中定义切点(Pointcut)和通知(Advice),切点指定需要拦截的方法,通知则指定需要在拦截方法前、后或者异常抛出时执行的代码 , 所有需要判断用户登录页面的方法就全部实现用户登录验证了 , 无需在每个方法中都实现用户登录验证.

简而言之 , AOP 是一种思想 , Spring AOP 是一个框架 , 提供了一种对 AOP 思想的实现 , 它们的关系和 loC 和 DI 类似.


二. 为什么要学习Spring AOP

想象一个场景 , 我们做后台系统时 , 除了注册和登录等几个功能无需做用户登录验证之外 , 其他几乎所有页面的 Controller 都需要先验证用户的登录状态 , 那么此时怎么处理呢?

之前的处理方式是所有的 Controller 都写一遍用户登录验证 , 然而当实现的功能越来越复杂 , 那么代码的冗余会越来越多 , 导致代码的可维护性变得非常差 , 那么如果能将这些冗余的代码统一处理 , 工作者只需专注于当前业务 , 开发效率就会大大增加. 因此对于这种功能统一 , 且使用地方较多的功能 , 就可以考虑 AOP 统一处理了.

除了统一用户登录验证之外 , AOP 还可以实现:

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

也就是说 AOP 可以扩充多个对象的某个能力 , 所以 AOP 可以说是 OOP (Objec Oriented Programming ) 面向对象编程的补充.


三. 学习 Spring AOP

3.1 AOP 的组成

3.1.1 切面 (Aspect)

切面(Aspect) 由切点(Pointcut) 和通知(Advice) 组成 , 而某一方面的具体内容就是一个切面 , 比如用户的登录判断就是一个切面 , 简而言之 , 切面就是一个特殊的类 , 里面包含了切点和通知.

3.1.2 切点 (Pointcut)

定义一个拦截规则 , 指在应用程序中需要拦截的方法集合,可以使用表达式或者正则表达式等方式进行定义。切点是一个抽象的概念,它并不代表具体的方法,而是代表一组方法,这些方法需要被拦截并执行通知。

3.1.3 通知 (advice)

执行 AOP 具体的业务逻辑 , 指在切点上执行的操作。通知可以在切点执行前、执行后、抛出异常时执行,以便实现不同的功能需求。

通知包括以下几种类型:

  • 前置通知(Before advice):在切点执行前执行的通知。

  • 后置通知(After advice):在切点执行后执行的通知,不管切点执行成功或者失败都会执行。

  • 返回通知(After returning advice):在切点执行成功后执行的通知。

  • 异常通知(After throwing advice):在切点抛出异常后执行的通知。

  • 环绕通知(Around advice):在切点执行前后都可以执行的通知,可以控制切点的执行。

3.1.4 连接点(Joinpoint)

所有可能触发切点的点就叫做连接点 , 指在应用程序中实际执行的方法,即切点所定义的方法的实际执行过程。连接点是一个具体的概念,它代表了程序中的一个具体的执行点,例如方法的调用、异常抛出、字段的访问等

AspectJ 支持三种通配符

  • : 匹配任意字符串 , 只匹配一个元素 (包 , 类 , 方法 , 方法参数)

… : 匹配任意字符 , 可以匹配多个元素 , 在表示类时 , 必须和 * 联合使用

+: 表示按类型匹配指定类的所有类 , 必须跟在类名后面 , 如 com.cad.Car+ , 表示继承该类的所有子类包括本身

切点表达式由切点函数组成 , 其中 execution() 是最常用的切点函数 , 用来匹配函数 , 语法为:

execution(<修饰符><返回类型><包.类.方法(参数)><异常>)

Spring AOP 快速入门

3.2 实现 Spring AOP

1. 添加 Spring Boot 的 AOP 框架
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Tips: 虽然 Spring 框架内置了原生 AOP , 但由于我们目前是 SpringBoot 项目 , 所以需要添加 SpringBoot 框架的 AOP.

Spring AOP 快速入门

2. 创建切面
//创建切面
@Aspect//表明此类为一个切面
@Component
public class UserAOP {

}
3. 创建切点
@Aspect
@Component
public class UserAOP {
//    定义切点 , 此处使用 AspectJ 语法 (配置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..)")
    public void pointcut(){
        
    }
}
4. 创建通知
//创建切面
@Aspect
@Component
public class UserAOP {
//    定义切点 , 此处使用 AspectJ 语法 (配置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.* (..))")
    public void pointcut(){
    }
//    前置通知
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("执行了前置通知: " + LocalDateTime.now());
    }
//    后置通知
    @After("pointcut()")
    public void doAfter(){
        System.out.println("执行流后置通知:" + LocalDateTime.now());
    }
//    环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("开始执行环绕通知");
        Object obj = joinPoint.proceed();
        System.out.println("结束执行环绕通知");
        return obj;
    }
}
5. 创建链接点
@RestController
public class UserController {
    @RequestMapping("/user/sayhi")
    public String sayhi(){
        System.out.println("执行了 sayhi 方法");
        return "hi springboot aop";
    }
}
6. 切点表达式说明

AspectJ 支持三种通配符

*: 匹配任意字符 , 只匹配一个元素 (包 , 类 , 方法 , 方法参数)

… : 匹配任意字符 , 匹配多个元素 , 在表示类时必须和 * 连用.

+: 表示按照类型匹配指定类的所有类 , 必须跟在类名之后 , 如 com.cad.Car+ , 表示继承该类的所有子类包括本身.

切点表达式由切点函数组成 , 其中 execution() 就是常见的切点函数 , 用来匹配方法 , 语法为:

execution(<修饰符><返回类型><包.类.方法(参数)><异常>)

修饰符和异常可以省略

Spring AOP 快速入门

表达式示例

  • execution(* com.example.demo.UserController.*(…)) 匹配UserController 类里的所有方法
  • execution(* com.example.demo.UserController+.*(…)) 匹配该类的子类包括该类的所有方法

3.3 Spring AOP 实现原理

Spring AOP 是构建在动态代理基础上 , 因此 Spring 对 AOP 的支持局限于方法级别的拦截.

Spring AOP 支持 JDK Proxy 和 CGLIB 方式实现动态代理. 默认情况下 , 实现了接口的类 , 使用 AOP 会基于 JDK 生成动态代理类 , 没有实现接口的类 , 会基于 CGLIB 生成代理类.

Spring AOP 快速入门

织入(Weaving): 代理的生成时机

织入就是把切面应用到目标对象并创建新的代理的过程 , 切面在指定的连接点被织入到目标对象中.

在目标对象的生命周期里有多个点可以织入:

  • 编译期: 切面在目标类编译时被织入. AspectJ 的织入编译器就是以这种方式织入切面的. 例如 lombok
  • 类加载期: 切面在目标类加载到 JVM 时被织入. 这种方式需要特殊的类加载器(ClassLoader). 它可以在目标类被引入应用之前增强该目标类的字节码.
  • 运行期: 切面在应用运行的某一时刻被织入. 一般情况下 , 在织入切面时 , AOP 容器会为目标对象动态创建一个代理对象. Spring AOP 就是以这种方式实现的.

Spring AOP 底层实现:

1.JDK 动态代理

速度快 , 通过反射调用目标方法

要求被代理的类一定要实现接口

2.CGLIB

通过实现代理类的子类来实现动态代理 , 但不能代理被 final 修饰的类和方法.

综上所述,JDK动态代理和CGLIB动态代理各有优缺点,应根据实际情况选择使用。如果目标类实现了接口,则建议使用JDK动态代理;如果目标类没有实现接口或者需要代理类中的非接口方法,则建议使用CGLIB动态代理。


总结

AOP 是对某方面功能的统一实现 , 它是一种思想 , Spring AOP 是对 AOP 的具体实现 , Spring AOP 可通过 AspectJ 注解的方式来实现 AOP 功能 , Spring AOP 的实现步骤是:

  1. 添加 AOP 支持框架
  2. 定义切面和切点
  3. 定义通知

Spring AOP 是通过动态代理的方式 , 在运行期间将 AOP 代码织入到程序中的 , 实现方式有两种 , JDK Porxy 和 CGLIB.文章来源地址https://www.toymoban.com/news/detail-488000.html

到了这里,关于Spring AOP 快速入门的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 什么是 AOP?对于 Spring IoC 和 AOP 的理解?

    AOP(Aspect-Oriented Programming) ,即 面向切面编程, 它与 OOP( ObjectOriented Programming, 面向对象编程) 相辅相成,提供了与OOP 不同的抽象软件结构的视角 在 OOP 中, 我们以 类(class) 作为我们的基本单元 而 AOP 中的基本单元是 Aspect(切面) IOC(Inverse of Control:控制反转) 是一种设计思想,

    2024年02月12日
    浏览(45)
  • 【Spring】Spring AOP入门及实现原理剖析

    AOP (Aspect-Oriented Programming) 是一种编程范式,它提供一种将程序中的横切关注点模块化的方式。横切关注点可以是日志、事务、安全等,它们不属于业务逻辑,但是又必须要与业务逻辑紧密耦合在一起。在 AOP 中,我们将这些横切关注点称为“切面”,它们独立于业务逻辑模块

    2024年02月17日
    浏览(44)
  • Spring AOP -- Spring入门保姆级教程(三)

    为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。 (博客的参考源码可以在我主页的资源里找到,如果在学习的

    2024年02月05日
    浏览(30)
  • 【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用

    【JavaEE】 AOP(1) 1.1 AOP 与 Spring AOP AOP ( A spect O riented P rogramming),是一种思想,即 面向切面编程 Spring AOP 则是一个框架,Spring项目中需要引入依赖而使用 AOP和Spring AOP的关系就相当于IoC和DI Spring AOP让开发者能够半自动的开发AOP思想下实现的功能 1.2 没有AOP的世界是怎样的

    2024年02月11日
    浏览(46)
  • Spring FrameWork从入门到NB - Spring AOP - 概念

    什么是AOP AOP - Aspect Oriented Programming的缩写,面向切面编程。 面向切面编程AOP是面向对象程序设计OOP的一个补充或扩展,是为了解决OOP在一些共性问题上的不足应运而生的。比如记录日志、事务处理、性能分析等等与业务无关的需求,需要发生在很多类的很多方法上,而需求

    2024年02月13日
    浏览(44)
  • 114、Spring AOP是如何实现的?它和AspectJ有什么区别?

    其实,AOP只是一种编程思想,表示面向切面编程,如果想实现这种思想,可以使用动态代理啊,第三方的框架 AspectJ啊等等。 Spring AOP是利用的动态代理机制 如果一个Bean实现了接口,那么就会采用JDK动态代理来生成该接口的代理对象 如果一个Bean没有实现接口,那么就会采用

    2024年02月14日
    浏览(41)
  • Spring AOP入门指南:轻松掌握面向切面编程的基础知识

    1.1 什么是AOP? AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构。 OOP(Object Oriented Programming)面向对象编程 我们都知道OOP是一种编程思想,那么AOP也是一种编程思想,编程思想主要的内容就是指导程序员该如何编写程序,所以它们两个是不同

    2024年02月03日
    浏览(67)
  • Spring 为什么要用三级缓存来解决循环依赖(AOP),二级缓存不行吗

    解决有代理对象的循环依赖不一定要三级缓存,用二级甚至一级也能解决,下面讨论下Spring为什么选择三级缓存这个方案。 Spring最开始是没有三级缓存的,后面版本因为引入了AOP,有了代理对象,又因为存在循环依赖,为了保证依赖注入过程注入的是代理对象,且不完全打破

    2024年04月26日
    浏览(37)
  • Spring02-Spring注解的使用、基于注解的IOC、纯注解配置、整合Junit、AOP入门、基于配置文件的AOP、切入点表达式、基于配置的文件环绕通知

    学习基于注解的 IOC 配置,即注解配置 和 XML 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。 关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯 , 所以这两种配置方式我们都需要掌握。 把 Spring 的 xml 配置内容改为使用

    2024年02月03日
    浏览(74)
  • Spring入门&控制反转(或依赖注入)&AOP的关键概念& 多配置文件&与web集成

    目录 1. 什么是spring,它能够做什么? 2. 什么是控制反转(或依赖注入) 3. AOP的关键概念 4. 示例 4.1 创建工程 4.2 pom文件 4.3 spring配置文件 4.4 示例代码 4.4.1 示例1 4.4.2 示例2 (abstract,parent示例) 4.4.3 使用有参数构造方法创建javaBean 4.4.4 init-method:指定bean的初始化方法 4.4.5 复杂属

    2024年02月09日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包