Spring-AOP-加强

news2024/11/24 2:00:00

目录

简略介绍

AOP是如何实现的

实现时机

实现原理


  • 简略介绍

  • AOP(Aspect-Oriented Programming),即面向切面编程,用人话说就是把公共的逻辑抽出来,让开发者可以更专注于业务逻辑开发
  • 和IOC一样,AOP也指的是一种思想
  • AOP思想是OOP(Object-Oriented Programming)的补充
  • OOP是面向类和对象的,但是AOP则是面向不同切面的
  • 一个切面可以横跨多个类和对象去操作,极大的丰富了开发者的使用方式,提高了开发效率
  • 譬如,一个订单的创建,可能需要以下步骤:
    • 1. 权限校验
    • 2. 事务管理
    • 3. 创建订单
    • 4. 日志打印
  • 如果使用AOP思想,我们就可以把这四步当成四个“切面”,让业务人员专注开发第三个切面,其他三个切面则是基础的通用逻辑,统一交给AOP封装和管理
  • 使用"横切"技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点
    • 业务处理的主要流程是核心关注点(业务的主要功能),与之关系不大的部分是横切关注点(非核心、额外增加的功能)
    • 横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物
    • 用户下单为例子
      • 核心关注点:创建订单
      • 横切关注点:记录日志、控制事务
    • AOP 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来
  • Spring AOP有如下概念:

  • 对于通知类型来说:

    • 1. 前置通知(Before):在目标方法被调用之前调用通知功能
    • 2. 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么
    • 3. 返回通知(After-returning):在目标方法成功执行之后调用通知
    • 4. 异常通知(After-throwing):在目标方法抛出异常后调用通知
    • 5. 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
    • 同一个aspect,不同advice的执行顺序:
      • 1-没有异常情况下的执行顺序:
        • around before advice
        • before advice
        • target method执行
        • around after advice
        • after advice
        • afterReturning
      • 2-有异常情况下的执行顺序:
        • around before advice
        • before advice
        • target method执行
        • around after advice
        • after advice
        • afterThrowing:异常发生
        • java.lang.RuntimeException:异常发生
  • AOP是如何实现的

  • 实现时机
    • 参考Bean的初始化流程-SpringBean的初始化流程-CSDN博客
    • 从Bean的初始化流程中来讲,Spring的AOP会在bean实例的初始化已完成,进行初始化后置处理即AbstractAutoProxyCreator#postProcessBeforeInstantiation中,生成代理:

  • 实现原理
    • Spring AOP 是通过代理模式实现的,具体有两种实现方式,一种是基于Java原生的动态代理,一种是基于cglib的动态代理
    • Spring AOP 默认使用标准的JDK动态代理进行AOP代理;这使得任何接口都可以被代理
    • 但是JDK动态代理有一个缺点,就是它不能代理没有接口的类
    • 所以Spring AOP就使用CGLIB代理没有接口的类
    • 默认情况下,如果一个业务对象没有实现一个接口,就会使用CGLIB

    • 当然代理这种设计模式也有动态代理和静态代理之分,可以参考这篇文章:Java基础---动态代理-CSDN博客
    • Spring AOP and AspectJ AOP
      • AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理
      • 什么是静态代理
        • 这种代理方式需要代理对象和目标对象实现一样的接口
        • 由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在
        • 通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的
      • 什么是动态代理
        • 在程序运行时,运用反射机制动态创建而成,无需手动编写代码
        • 不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
      • 静态代理的代表为AspectJ;动态代理则以Spring AOP为代表
      • (1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象
      • (2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
    • JDK动态代理和CGLIB动态代理
      • Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
      • 具体使用哪种方式生成代理对象由 AopProxyFactory 根据 AdvisedSupport 对象的配置来决定
      • 默认的策略是如果目标类是接口,则使用 JDK 动态代理技术,否则使用 Cglib 来生成代理
      • JDK动态代理只提供接口的代理,不支持类的代理
        • 又被称为接口代理
        • 动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用JDK动态代理
        • JDK中生成代理对象主要涉及的类有java.lang.reflect Proxy,主要方法为

          • 代理对象拥有目标对象相同的方法【因为参数二指定了对象的接口,代理对象会实现接口的所有方法】
          • 用户调用代理对象的什么方法,都是在调用处理器的invoke方法【被拦截】
          • 使用JDK动态代理必须要有接口【参数二需要接口】
        • 核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;
        • 接着,Proxy利用 InvocationHandler 动态创建一个符合某一接口的的实例,生成目标类的代理对象
      • 静态代理和动态代理的区别
        • 静态代理需要自己写代理类-->代理类需要实现与目标对象相同的接口
        • 而动态代理不需要自己编写代理类--->(是动态生成的)
      • 使用静态代理时:如果目标对象的接口有很多方法的话,那我们还是得一一实现,这样就会比较麻烦
      • 使用JDK动态代理时:代理对象的生成,是利用JDKAPI,动态地在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型),并且会默认实现接口的全部方法
      • 为什么jdk动态代理必须基于接口;原因如下:
        • 1、生成的代理类继承了Proxy,由于java是单继承,所以只能实现接口,通过接口实现方法
        • 2、从代理模式的设计来说,充分利用了java的多态特性,也符合基于接口编码的规范
        • 3、动态代理是通过反射来实现的,而且接口不依赖实现,才能体现动态代理的优点啊;如果是一个实体类怎么能是动态代理呢?
      • 如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类
      • CGLIB(Code GenerationLibrary),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP
        • 也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能
        • 使用cglib就是为了弥补JDK动态代理的不足【动态代理的目标对象一定要实现接口】
        • 如果想代理没有实现接口的类,就可以使用CGLIB实现
        • CGLIB是通过继承的方式做的动态代理,因此如果存在某个类被标记为final,private方法和static方法,那么它是无法使用CGLIB做动态代理的
    • 静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理
    • 小结:
      • 0. 通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过 SpringAOP 框架触发的代码段;目标对象是被一个或者多个切面所通知的对象,也指被通知(advised)对象;代理是通知目标对象后创建的对象;从客户端的角度看,代理对象和目标对象是一样的
      • 1. 静态代理实现较简单,只要代理对象对目标对象进行包装,即可实现增强功能,但静态代理只能为一个目标对象服务,如果目标对象过多,则会产生很多代理类
      • 2. JDK动态代理需要目标对象实现业务接口,代理类只需实现InvocationHandler接口
      • 3. JDK动态代理生成的类为 lass com.sun.proxy.$Proxy4,cglib代理生成的类为classcom.cglib.UserDao$$EnhancerByCGLIB$$552188b6
      • 4. 静态代理在编译时产生class字节码文件,可以直接使用,效率高
      • 5. JDK动态代理必须实现InvocationHandler接口,通过反射代理方法,比较消耗系统性能,但可以减少代理类的数量,使用更灵活
      • 6. cglib代理无需实现接口,通过生成类字节码实现代理,比反射稍快,不存在性能问题,但cglib会继承目标对象,需要重写方法,所以目标对象不能为final类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1098150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动化测试框架中如何记录日志更加已读 ?一文介绍使用loguru来管理日志的心得。

只要做代码开发,记录日志必不可少的 ,对于像我这样的测试开发同学也是 ,你在编写自动化时如何记录日志 ?怎么要日志记录更容易已读 ?如何备份日志文件 ? 这都是我们在编写代码时要考虑的问题 ,如…

JNI 的数据类型以及和Java层之间的数据转换

JNI的数据类型和类型签名 数据类型 JNI的数据类型包含两种:基本类型和引用类型。 基本类型主要有jboolean、jchar、jint等,它们和Java中的数据类型的对应关系如下表所示。 JNI中的引用类型主要有类、对象和数组,它们和Java中的引用类型的对…

ICC2:如何抓取“no net“的shape和via

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 pr过程中(尤其是eco)会产生一些no net的shape或via,它们会造成drc和lvs问题,但是常规的办法无法把他们抓出来,下面分享可以获取no net的方法…

数字化时代下,汽车行业如何突破现有营销困境?

之前三年的“口罩”时期,给全球和中国汽车市场带来不小影响,汽车销售市场整体下滑,传统营销模式很难适应现阶段汽车营销需求,那么在当下,汽车行业应该如何突破现有营销困境呢?接下来就由媒介盒子跟大家聊聊…

如何同步 Github 和 Gitee的仓库代码

一、从github导入仓库,手动同步 在 Gitee 的项目主页,导入的仓库会会有一个同步的按钮,你只用点一下,即可与 Github 同步更新,但是注意这里的同步功能默认是强制同步。有点麻烦的是,我们需要在推送到 Githu…

推理成本增加10倍?对文心大模型4.0的一些猜想

夕小瑶科技说 原创 作者 | 卖萌酱 大家好,我是卖萌酱。 相信不少小伙伴这几天都听到了消息,在期待下周即将发布的文心大模型4.0。我们的几个读者群里也发生了相关的讨论: 讨论的核心主要围绕以下两个话题展开: 文心4.0能不能打过…

git操作说明

SourceURL:file:///home/kingqi/桌面/git操作说明.doc 本地建立仓库 mkdir namebao cd namebao pwd git init 初始化 cd .git/ gedit config 本地存储 进入目录上传全部文件 git add . 提交 git commit -m “说明” 远程提交 复制gitee或者github仓库链接 可以直…

前端开发tips

vue配置启动项目自动打开浏览器 打开package.json找到启动命令npm run dev 跟npm run serve(这两种命令都可以) 后面增加 --open Vue项目设置路径src目录别名为 Vue2 编辑vue.config.js内容如下: const { defineConfig } require(vue/cli-service)const path…

使用Cython对Python进行提速优化

因为常常使用Python,经常能感觉到和C,Java来说Python的速度太慢了。其中很大程度上是因为Python的类型是动态的,在解释类型方面花了较长时间。在调研过程中,发现给Python提速一个比较可行的方案是用Cython改写。 Cython的原理&am…

零售数据分析师熬夜整理:人、货、场、供、财这样做

在零售数据分析中,人、货、场、供、财数据分析非常重要,它们分别是指人员、商品、场所、供应和财务,对这些要素进行数据分析,可以更好地了解市场需求、优化商品供应链、调整销售策略和提高盈利能力。零售数据量大、分析指标多且复…

蓝桥·算法双周赛

文章目录 三带一数树数分组健身契合匹配奇怪的线段 一、三带一 本题思路:本题看了数据范围可以直接暴力解决。 #include <bits/stdc.h>int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int T;std::cin>>T;while(T-…

C#网络爬虫实例:使用RestSharp获取Reddit首页的JSON数据并解析

Reddit 是一个非常受欢迎的分享社交新闻聚合网站&#xff0c;用户可以在上面发布和内容。我们的目标是抓取 Reddit 首页的数据 JSON&#xff0c;以便进一步分析和使用。 C#技术概述&#xff1a;C#是一种流行的编程语言&#xff0c;它具有流畅流畅的特点&#xff0c;非常适合开发…

用手势识别来测试视力?试试用百度AI来实现想法

文章目录 ⭐ 前言⭐ 灵感来源⭐ 项目准备⭐ 项目实现⭐ 不足与展望 ⭐ 前言 10月17日&#xff0c;以“生成未来&#xff08;PROMPT THE WORLD&#xff09;”为主题的百度世界2023将在北京首钢园举办。百度创始人、董事长兼首席执行官李彦宏将带来以“手把手教你做AI原生应用”…

【微信小程序开发】基础语法篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.视图层 1.数据绑定 wxml js 2 .列…

android CountDownTimer倒计时随时随地开启或关闭

前言 业务上有个需求&#xff0c;在心跳被触发时需要记录一个时间 当心跳断开后120s需要断开连接 如果收到心跳包就重置这个定时器的时间 代码实现 private CountDownTimer mTimer; private boolean mIsTimerRunning false;if (!mIsTimerRunning) {// 启动定时器startTimer…

消息队列学习分享

消息队列学习 消息队列来解决问题 &#xff08;1&#xff09;异步处理 消息通知、日志管理、更新统计数据等步骤 &#xff08;2&#xff09;流量控制 如何避免过多的请求压垮我们的系统&#xff1f; 比如一个秒杀系统&#xff0c;网关在收到请求后&#xff0c;将请求放入…

基于Pytest+Requests+Allure实现接口自动化测试

一、整体结构 框架组成&#xff1a;pytestrequestsallure设计模式&#xff1a; 关键字驱动项目结构&#xff1a; 工具层&#xff1a;api_keyword/参数层&#xff1a;params/用例层&#xff1a;case/数据驱动&#xff1a;data_driver/数据层&#xff1a;data/逻辑层&#xff1a…

数字化时代,数据仓库究竟是干什么的?

无论你是否专门从事大数据开发&#xff0c;作为一个开发人员&#xff0c;应该都听说过数据仓库的概念&#xff0c;那你知道为什么会出现数据仓库&#xff1f;数据仓库究竟是干嘛的吗&#xff1f;有什么价值和意义呢&#xff1f;那么本文就带到入门&#xff0c;揭开数据仓库的面…

嵌入式软硬分工与职业发展

嵌入式软硬分工与职业发展&#xff1a; 嵌入式系统分为软件和硬件两个方向。大公司通常明确员工从事嵌入式软件或硬件工作&#xff0c;分工合理利用经验解决问题。小公司可能综合工作&#xff0c;但长期不利深入学习和发展&#xff0c;对个人竞争力不利。嵌入式软件一般指底层…

财报解读:百事业绩继续超预期,无糖布局将带来新爆发?

7月份以来&#xff0c;美国市场通胀“二次反弹”&#xff0c;叠加新型减肥药在北美市场持续风靡&#xff0c;外界普遍预期食品饮料品类的消费将受到冲击。 然而&#xff0c;在此环境下&#xff0c;行业巨头百事仍然交出了一份全面超预期的三季报&#xff0c;并且还有力回应了新…