返回顶部
首页 > 资讯 > 后端开发 > JAVA >SpringAOP面向切面编程
  • 546
分享到

SpringAOP面向切面编程

javaspringAOP面向切面动态代理 2023-10-11 20:10:40 546人浏览 薄情痞子
摘要

文章目录 一. AOP是什么?二. AOP相关概念三. SpringAOP的简单演示四. SpringAOP实现原理 一. aop是什么? AOP(Aspect Oriented Prog

文章目录

一. aop是什么?

AOP(Aspect Oriented Programming):面向切面编程,它是一种编程思想,是对某一类事情的集中处理它能够在不改原有代码的前提下对其功能进行增强,就是你代码已经写好了,使用 AOP 可以在不改动代码的前提下增强功能,如对于一个功能,可以基于 AOP 完成对该功能执行效率的计算,能够在功能正式执行前或者执行后,添加其他的功能执行,能够在该功能发生异常后,对其异常进行处理。

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

如果不使用 AOP,我们就需要在每一个 Controller 层都写一遍验证用户是否已经登录的逻辑,如果你实现的功能有很多,并且这些功能都需要进行登录验证,那你就需要编写大量重复的代码, 这样代码修改和维护的成本也会很高。

但如果使用 AOP,在进入核心的业务代码之前会做统一的一个拦截,去验证用户是否登录,验证通过的就可以继续请求,此时就不需要每一处都写相同的用户登录逻辑了。

除了登录验证功能之外,还有很多功能也可以使用 AOP,比如:

  • 统一日志记录与持久化。
  • 统一方法执行时间统计。
  • 统一数据返回格式。
  • 统一处理程序中的异常。
  • 统一事务的开启与提交。

也就是说使用 AOP 可以扩充多个对象的某个能力,所以 AOP 可以说是 OOP (Object Oriented Programming,面向对象编程)的补充和完善,它可以将横切关注点从应用程序的主业务逻辑中分离出来,使得这些关注点可以集中处理,从而提高代码复用性、可维护性和系统可扩展性。

springAOP 是一个框架,提供了对 AOP 的实现,与 ioc 与 DI 的关系类似。

二. AOP相关概念

  1. 切面(Aspect)–> 类:某一方面的具体内容处理(AOP实现的某个功能的集合)就是一个切面,由切点(Pointcut)和通知(Advice)组成 ;比如用户登录判断就是一个切面(接口对于登录权限的校验)。
  2. 切点(Pointcut)–>方法:定义拦截规则;比如切面对于哪些接口需要进行判断拦截。
  3. 连接点(Joinpoint):所有可能触发切点的点就是连接点(被这个切面所处理的点)。
  4. 通知(方法的具体实现):执行 AO P业务(具体需要执行的拦截方法)。

在 Spring 切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件后会调用对应满足条件的方法:

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

AOP 整个组成部分的概念如下图所示,以多个⻚⾯都要访问⽤户登录权限为例:

img

三. SpringAOP的简单演示

1️⃣第一步,添加 Spring Boot AOP 依赖支持。

SpringBoot 项目中导入 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>    <version>2.7.2</version></dependency>

2️⃣第二步,定义切面,我们使用@Aspect注解将类标识为切面类,并使用注解 @Component 将类实例化到容器中。

package com.example.demo.common;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect // 定义切面@Componentpublic class UserAspect {    }

3️⃣第三步,定义切点,配置拦截规则,可以使用AspectJ表达式类来进行描述,它的语法格式如下:

切入点表达式标准格式:动作关键字(访问修饰符  返回值  包名./接口名.方法名(参数) 异常名)

AspectJ ⽀持三种通配符:

  • *:匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)。

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

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

其中访问修饰符和异常可以省略,比如下面这个表达式:

img

任意声明一个方法,不需要具体实现,使用注解@Pointcut修饰,里面的value属性填写AspectJ表达式,这个方法就可以视为连接目标方法的一个切点。

但要注意,这种表达式的书写是非常繁琐的,目前有更好的AOP实现,可以更加灵活的配置,也就是说这里的写法其实并不常用。

代码实现:

@Aspect // 定义切面@Componentpublic class UserAspect {    // 切点    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")    public void pointcut() {    }}

4️⃣第四步,创建通知。

有了切点,要对切点处的方法进行相关处理,需要编写具体的增强方法,也就是通知,下面我们需要在切面类中简单编写几个方法来表示通知,通知就是将共性功能抽取出来后形成的方法。

要注意对于环绕通知,由于在实现增强方法时,需要介入到方法执行前和后,那么必须得获取到目标的方法,不然无法控制你实现的那些代码是在目标方法执行前执行的,哪些方法是在目标方法执行后执行的。

对于这项工作,SpringAOP 已经帮我们做了,所有的切点方法都已经加载到ProceedingJoinPoint对象当中,只要调用proceed方法就能够执行目标方法。

package com.example.demo.common;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect // 定义切面@Componentpublic class UserAspect {    // 切点    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")    public void pointcut() {    }    // 前置通知通知    @Before("pointcut()")    public void doBefore() {        System.out.println("执行了前置通知");    }    // 后置通知    @After("pointcut()")    public void doAfter() {        System.out.println("执行了后置通知");    }    // 环绕通知    @Around("pointcut()")    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {        System.out.println("环绕通知执行之前");        // 执行目标方法        Object result = joinPoint.proceed();        System.out.println("环绕通知执行之后");        return result;    }}

5️⃣第五步,创建连接点。

package com.example.demo.controller;import org.springframework.WEB.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/user")public class UserController {    @RequestMapping("/getuser")    public String getUser(){        System.out.println("do getUser");        return "get user";    }    @RequestMapping("/deluser")    public String delUser(){        System.out.println("do delUser");        return "del user";    }}

🍂此时,就可以启动 SpringAOP 了,然后通过浏览器去访问定义的这两个连接点,看通知效果。

img

img

🍂我们可以在Controller层再创建一个ArticleController类用来对照,访问一下看此时是否会执行通知。

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/art")public class ArticleController {    @RequestMapping("/getart")    public String getArticle(){        System.out.println("do getArticle");        return "getArticle";    }}

结果如下:

因为我们设置的拦截规则不包含这个类,也就不会执行通知了。

img

img

四. SpringAOP实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截(使用动态代理技术实现方法的调用)。

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

img

下面简单的来说一下原理,首先,要有一个目标对象,在上面的例子中,目标对象就是UserController,然后通过基于这个目标对象,创建一个代理类,并在某一规定的时机生成,这个时机就是织入,最后在这个代理类上加上一些增强的方法,这个过程就叫做引入

🎯下面又出来了一组相关概念:

目标对象:代理的目标对象。

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

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

引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

🍂JDK Proxy 与 CGLIB 的区别:

  1. 出身不同,一个由 JDK 实现,一个由 CGLIB 实现。
  2. 实现不同,JDK Proxy 要求代理类实现接口才能实现代理,它只能代理接口中定义的方法;CGLIB 是通过实现代理类的子类完成动态代理,可以为任意一个类创建代理对象,包括没有实现任何接口的类,它能够代理类中所有非 final 的方法。
  3. 性能不同,JDK7 之后 JDK Proxy 性能是略高于 CGLIB 的; 而在 JDK7 之前 CGLIB 性能是略高于 JDK Proxy 的。

来源地址:https://blog.csdn.net/Trong_/article/details/132745439

--结束END--

本文标题: SpringAOP面向切面编程

本文链接: https://lsjlt.com/news/428765.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringAOP面向切面编程
    文章目录 一. AOP是什么?二. AOP相关概念三. SpringAOP的简单演示四. SpringAOP实现原理 一. AOP是什么? AOP(Aspect Oriented Prog...
    99+
    2023-10-11
    java spring AOP 面向切面 动态代理
  • SpringAOP详解面向切面编程思想
    目录1. 什么是 Spring AOP2. AOP 的组成2.1 切面 (Aspect)2.2 切点 (Pointcur)2.3 连接点 (Join Point)2.4 通知 (Ad...
    99+
    2024-04-02
  • JAVA:面向切面编程AOP
    一、定义         把某一些功能提取出来与某一对象进行隔离,提取之后可以对某哥单方面的功能进行修改和扩展         也就是把众多方法中的的所有公共代码抽取出来,放到某个地方集中管理         对业务逻辑的各个部分进行了隔离...
    99+
    2023-09-12
    java AOP
  • spring6-AOP面向切面编程
    面向切面编程AOP 1、场景模拟1.1、声明接口1.2、创建实现类1.3、创建带日志功能的实现类1.4、提出问题 2、代理模式2.1、概念2.2、静态代理2.3、动态代理2.4、测试 ...
    99+
    2023-10-21
    java 后端 spring aop 面向切面编程
  • AOP面向切面编程思想。
    目录 一、AOP工作流程 1、基本概念 2、AOP工作流程  二、AOP核心配置 1、AOP切入点表达式 2、AOP通知类型 三、AOP通知获取数据 1、获取参数 2、获取返回值 3、获取异常  四、AOP事务管理 1、Spring事务简介...
    99+
    2023-09-06
    spring java 后端
  • Python 切面编程秘籍:揭开面向切面编程的奥秘
    ...
    99+
    2024-04-02
  • 解析Spring中面向切面编程
    目录一、AOP——另一种编程思想1.1、什么是 AOP1.2、为什么需要 AOP1.3、AOP 实现分类二、AOP 术语三、初步认识 Spring AOP3.1、Spring AOP...
    99+
    2024-04-02
  • 【Spring】面向切面编程详解(AOP)
    文章目录 一、AOP概述什么是AOPAOP应用场景 二、AOP的基本术语术语介绍术语举例详解 三、AOP实例说明四、通知类型详解概述前置通知后置通知环绕通知最终通知 六、AOP实现声明式事务...
    99+
    2023-08-30
    spring java 后端
  • Spring面向切面编程AOP详情
    目录1. 面向切面编程2. AOP核心概念3. AOP的实现4. Spring 对AOP支持4.1 支持@Aspect4.2 声明一个切面4.3 声明一个切入点4.4 声明增强5. ...
    99+
    2024-04-02
  • Java面向切面编程怎么实现
    在Java中实现面向切面编程,可以使用以下几种方式:1. 使用代理模式:通过创建代理类,将横切逻辑封装在代理类中,然后在实际业务类中...
    99+
    2023-08-08
    Java
  • 揭秘 Python 面向切面编程的神秘面纱
    ...
    99+
    2024-04-02
  • Javascript中怎么实现面向切面编程
    本篇文章为大家展示了Javascript中怎么实现面向切面编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。面向切面编程(Aspect-oriented progr...
    99+
    2024-04-02
  • java开发AOP面向切面编程入门
    目录引言不好的解决方案面向过程的解决方案使用继承解决方案使用聚合的解决方案面向切面的编程基本概念基于Spring面向切面程序实现小结引言 在实际应用场景中,我们封装一个学生的类,这个...
    99+
    2024-04-02
  • Python 面向切面编程 AOP 及装饰器
    目录什么是 AOP装饰器函数装饰器类装饰器1、函数装饰函数2、类装饰函数3、函数装饰类4、类装饰类什么是 AOP AOP,就是面向切面编程,简单的说,就是动态地将代码切入到类的指定方...
    99+
    2024-04-02
  • Spring中怎么实现面向切面编程
    Spring中怎么实现面向切面编程?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、AOP——另一种编程思想1.1、什么是 AOPAOP (Aspect Ori...
    99+
    2023-06-15
  • Java面向切面编程AOP怎么实现
    这篇文章主要介绍“Java面向切面编程AOP怎么实现”,在日常操作中,相信很多人在Java面向切面编程AOP怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java面向切面编程AOP怎么实现”的疑惑有所...
    99+
    2023-06-04
  • Java aop面向切面编程(aspectJweaver)案例详解
    面向切面编程的目的就是:在不改变别人的代码的前提下,在别人代码方法执行前或后,执行(切入自己的逻辑) 准备:idea+maven+aspectjweaver-1.8.9.jar ...
    99+
    2024-04-02
  • Java aop面向切面编程有什么特点
    面向切面编程(AOP)是一种软件开发范式,用于将横切关注点(cross-cutting concerns)与主要业务逻辑分离。 A...
    99+
    2024-03-01
    Java
  • Spring框架AOP面向切面编程原理全面分析
    目录1.什么是AOPAOP面向切面的优势AOP需要添加的依赖2.简述AOP工作运行原理动态创建的总结:3.使用Spring创建AOP测试类Spring.xml1.什么是AOP AOP...
    99+
    2024-04-02
  • Springboot怎样使用Aspectj实现AOP面向切面编程
    Springboot怎样使用Aspectj实现AOP面向切面编程,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。要在 Springboot中声明 AspectJ 切面需在 IOC...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作