AOP实现原理

文章详细介绍了JDK动态代理的原理,包括反射优化,以及CGLIB代理的工作机制,强调了MethodInterceptor的角色。同时,讨论了Spring如何选择代理方式,重点讲述了切点匹配规则和事务增强的实现,提到了AnnotationAwareAspectJAutoProxyCreator在处理@Aspect切面和创建代理对象中的作用。
摘要由CSDN通过智能技术生成

JDK代理原理

  

 添加返回值

 将方法只加载一次

代理对象也传进来 

JDK

方法反射优化

  1. 前 16 次反射性能较低

  2. 第 17 次调用会生成代理类,优化为非反射调用

  3. 会用 arthas 的 jad 工具反编译第 17 次调用生成的代理类

为了把反射调用优化成正常调用 新建了一个代理类

cglib代理原理

和 jdk 动态代理原理查不多

  1. 回调的接口换了一下,InvocationHandler 改成了 MethodInterceptor

  2. 调用目标时有所改进,见下面代码片段

    1. method.invoke 是反射调用,必须调用到足够次数才会进行优化

    2. methodProxy.invoke 是不反射调用,它会正常(间接)调用目标对象的方法(Spring 采用)

    3. methodProxy.invokeSuper 也是不反射调用,它会正常(间接)调用代理对象的方法,可以省略目标对象

 methodProxy创建过程 需要传的参数 后边一个是增强方法 一个是方法重载后的原始方法(继承)

 创建MethodProxy 时 就会创建这两个fastclass类

  1. 当调用 MethodProxy 的 invoke 或 invokeSuper 方法时, 会动态生成两个类

    • ProxyFastClass 配合代理对象一起使用, 避免反射

    • TargetFastClass 配合目标对象一起使用, 避免反射 (Spring 用的这种)

  2. TargetFastClass 记录了 Target 中方法与编号的对应关系

    • save(long) 编号 2

    • save(int) 编号 1

    • save() 编号 0

    • 首先根据方法名和参数个数、类型, 用 switch 和 if 找到这些方法编号

    • 然后再根据编号去调用目标方法, 又用了一大堆 switch 和 if, 但避免了反射

  3. ProxyFastClass 记录了 Proxy 中方法与编号的对应关系,不过 Proxy 额外提供了下面几个方法

    • saveSuper(long) 编号 2,不增强,仅是调用 super.save(long)

    • saveSuper(int) 编号 1,不增强, 仅是调用 super.save(int)

    • saveSuper() 编号 0,不增强, 仅是调用 super.save()

    • 查找方式与 TargetFastClass 类似

  4. 为什么有这么麻烦的一套东西呢?

    • 避免反射, 提高性能, 代价是一个代理类配两个 FastClass 类, 代理类中还得增加仅调用 super 的一堆方法

    • 用编号处理方法对应关系比较省内存, 另外, 最初获得方法顺序是不确定的, 这个过程没法固定死

  5.  调用invoke的时候 就会调用fastclass内部的invoke

核心是知道你的方法名通过创建methodproxy对象 传递给fastclass 在这个类里调用target对象的方法 

 创建代理对象的时候 因为是子类继承父类 所以会知道父类所有方法和参数,然后再代理类里面创建methodproxy对象  把每个方法和参数都传给这个对象  当创建这个对象的时候 就会动态生成两个类 :

ProxyFastClass 配合代理对象一起使用, 避免反射

TargetFastClass 配合目标对象一起使用, 避免反射 (Spring 用的这种)

这两个类把你methodproxy对象 传进来的方法和参数都 赋予一个唯一的编号  (通过最终调用getindex方法)

 当你调用invoke的时候 你把对象和参数传进来  就会进入到

使用methodproxy的时候就已经  获得了它的匹配规则了。当你在外部调用invoke的时候 会根据你穿的方法参数 获得方法对应的编号   再调用内部的invoke方法  把那个编号传进去 内部就知道该调用对象的哪个方法了

 执行这一步的时候 方法和编号就已经匹配上了

Spring选择代理的规则

这个就是Spring选择代理的方法

把目标类、切面、目标类是否实现接口 和这个proxyTargetClass的值 赋值给工厂 由工厂再生成 代理对象工厂内部封装了那两种(jdk cglib)的方法

 》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

根据切点表达式来判断你这个方法执行的时候要不要功能增强

切点匹配 有两种方式

匹配检验 检验一下是不是成功 成功了再进行代理

 一种是根据路径

一种是根据注解 

调用match方法进行匹配是否为切点

AspectJ的方法匹配有局限性

  1. 常见 aspectj 切点用法

  2. aspectj 切点的局限性,实际的 @Transactional 切点实现

@Transcational 事务增强并没用以上两种方法 因为类、和接口也有可能加这个注解

而上面两种只能匹配方法。

它只能匹配方法 不能匹配 类 接口等 

实现的原理类似下面

 用这种方法可以实现解析类 和接口上的注解

Bean的一个后处理器AnnotationAwareAspectJAutoProxyCreator

创建代理对象的时候根据目标类 会在容器里找到和这个代理对象匹配的有资格的切面类,

同时也会把扫描到的高级切面转换为低级切面

 知道切面之后应该就赋值给这个工厂 再由工厂创建代理对象

代理对象内部已经有重新写的invoke方法可以增强功能了(切面中包含了你需要增强的功能

直接就写到哪个handler类里了)

  1. AnnotationAwareAspectJAutoProxyCreator 的作用

    • 将高级 @Aspect 切面统一为低级 Advisor 切面

    • 在合适的时机创建代理

以下是这个处理器的两个方法

  1. findEligibleAdvisors 找到有【资格】的 Advisors

    • 有【资格】的 Advisor 一部分是低级的, 可以由自己编写, 如本例 A17 中的 advisor3

    • 有【资格】的 Advisor 另一部分是高级的, 由解析 @Aspect 后获得

  2. wrapIfNecessary

    • 它内部调用 findEligibleAdvisors, 只要返回集合不空, 则表示需要创建代理

    • 它的调用时机通常在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行

这两个方法 第一个是找到容器中所有与Target 匹配的切面(调用target类的方法)

然后返回所有和他匹配的切面

第二个方法是 如果找到了 切面 返回值不为空就会创建代理对象

 

代理对象创建于初始化之后(正常顺序) 

当存在循环依赖情况

 这时候Bean1执行实例化后 在进行依赖注入的时候 需要bean2来注入 但是bean2还没创建 所以只能先去创建bean2  但是bean2还需要bean1的依赖注入 所以只能先创建bean1的代理对象给bean2注入 然后bean2初始化完成后 再给bean1进行依赖注入  

这就是代理对象在依赖注入前被创建的情况

但是增强功能应该在初始化之后才增加 这样才有意义

切面的排序可以通过@Order注解来改变 

但是@Order注解和@Bean一起用会失效

标记在方法上也失效

 高级切面转换为低级切面过程

因为你高级切面可能有很多通知方法,低级切面只能一对一

所以需要转换

就是把切面里的通知方法解析出来

然后把你(增强的内容、切点(你需要增强的方法))和用factory创建通知对象

然后再把每一个低级的切面 封装成集合 就ok了

skr.~
关注 关注
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring源码解析之Aop
xxxzzzqqq_的博客
04-11 273
/ 缓存机制if (!// 判断该Bean是否已经被增强(advisedBeans为已经增强过的Bean)// 2.1.1 判断是否为基础类型(isInfrastructureClass)或者 2.1.2 判断是否需要跳过的Bean// 如果我们有一个自定义的TargetSource,则在此处创建代理。// 这段源码要抑制目标bean的不必要的默认实例化:TargetSource将以自定义方式处理目标实例。// 2.1.3 自定义目标资源,对于单实例Bean必定会返回null。
高级Spring之cglib 避免反射调用
qq_61313896的博客
01-31 470
高级Spring之cglib 避免反射调用
Spring AOP proxyTargetClass 行为表现总结
Details Inside Spring
11-11 1万+
proxyTargetClass true 目标对象实现了接口 – 使用CGLIB代理机制 目标对象没有接口(只有实现类) – 使用CGLIB代理机制 false 目标对象实现了接口 – 使用JDK动态代理机制(代理所有实现了的接口) 目标对象没有接口(只有实现类) – 使用CGLIB代理机制 ...
9、cglib demo分析以及methodProxyFastclass源码
飞飞好奇的专栏
11-07 5564
前言 上一节讲了say方法最终会转发,在demo中 cglib.CglibProxy#intercept这个里面用了 Object result = methodProxy.invokeSuper(o, objects); 这个invokeSuper是什么?如何实现代理类函数的调用 转发到 父类对应函数的调用. 这里就涉及methodProxy以及FastClass机制了。 这两者也是...
Spring注解驱动开发——AOP常用注解
紫罗兰与海棠的博客
01-10 1909
一、用于开启注解AOP支持的 @EnableAspectJAutoProxy (一) 作用 表示开启spring对注解aop的支持。它有两个属性,分别是指定采用的代理方式和 是否暴露代理对象,通过AopContext可以进行访问。 (三) 属性 proxyTargetClass: 指定是否采用cglib进行代理。默认值是false,表示使用jdk的代理。 exposeProxy: 指定是否暴露代理对象,通过AopContext可以进行访问。 (四) 细节 (1) proxyTargetClass 当使用J
Spring源码 之 AOP动态代理源码分析——基础篇
wenyixicodedog的博客
06-24 321
决定使用cglib还是jdk由于JdkDynamicAopProxy和ObjenesisCglibAopProxy都实现了AopProxy,所以刚才getProxy方法调用的时候使用哪种实现是在这里返回不同的实现类决定的。
spring aop实现原理
03-15
NULL 博文链接:https://zhang-yingjie-qq-com.iteye.com/blog/319927
深入浅析Springaop实现原理
09-02
AOP(Aspect-Oriented Programming,面向方面编程)是一种编程范式,旨在提供更好的模块化和组织代码的方式,...通过理解Spring AOP实现原理,开发者可以更好地设计和优化应用程序,提升系统架构的灵活性和可扩展性。
Java框架篇?spring AOP 实现原理
12-22
什么是AOP  AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共...
Spring AOP实现原理解析
08-28
Spring AOP实现原理解析 Spring AOP(Aspect-Oriented Programming)是一种面向方面编程的技术,它可以将公共行为封装到一个可重用模块中,以减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可...
aop实现原理
weixin_56267337的博客
11-20 315
AOP的介绍以及实现
JAVA基础:动态代理cglib原理(二)Fastclass 机制分析
qq_38940885的博客
02-25 1546
JDK动态代理的拦截对象是通过反射的机制来调用被拦截方法的,反射的效率比较低,所以CGLIB采用了FastClass的机制来实现对被拦截方法的调用。
面试问题-3
cfy的博客
03-10 105
今天是2021-3-1。 一。死锁 什么情况下会发生死锁?如何避免? 在多线程环境下,如果有至少两个线程,都持有对方需要的同步对象,那么就会导致对方因为获取不到自己的同步对象而无法操作共享数据,只能阻塞等待需要的同步对象被释放,这就是死锁。 错误示范: Synchronized(A){ ... Synchronized(B){ ... } } 解决建议: 避免一个线程同时持有多个同步对象 如果需要持有多个同步对象,使用lock.tryLock(timeout)定时锁来替代synchro
第九篇:Java之动态代理 Proxy和cglib
qq_40276626的博客
08-10 473
Spring框架是Java程序员熟知的框架。Spring有两大特性,IOC和AOPAOP就是我们熟悉的切面编程,和我们今天说的动态代理关系密切。 Java中动态代理有两种方式:Proxy和cglib 1、Proxy Proxy要求被代理的类必须要继承接口才能实现代理,实现Proxy需要四步 1、定义接口 interface PersonInterface{ public String print(String name); } 2、定义被代理的类 class Person implements
Spring学习总结(三)——Spring实现AOP的多种方式
weixin_30561177的博客
08-04 661
AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术。AOP是OOP的补充,是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP可以分为静态织入与动态织入,静态织入即在编译前将...
Spring AOP 介绍与应用
sxiaobei的博客
11-20 2651
SpringAOP想必大家都是比较清楚的,从spring 3.x版本出现之后,AOP的概念更加清晰,使用也更加方便。我看过很多书,讲解springaop,里面都有太多的概念,看到最后,还是不懂,有些云里雾里的,但是在使用了这么长时间以来,我觉得有些书上讲的太过繁琐了,或者说一下讲的太深入,太抽象让人难以理解。下面我会尽自己的可能让大家弄懂什么是AOP,并解释一个实际当中的应用实例,让大家真正理
SpringAop的optimize与proxyTargetClass有什么区别
Eric的专栏
11-19 2602
SpringAop中如果要手动添加通知的话就会用到ProxyFactoryBean这个类: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.o
Spring AOP中强制使用CGLIB代理
热门推荐
dushenzhi的专栏
10-09 2万+
spring官方文档中关于aop的描述如下:Spring AOP defaults to using standard JDK dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.Spring AOP can also use CGLIB proxies. T
springaop实现原理
最新发布
05-10
Spring AOP实现原理主要是基于动态代理,它通过代理对象来控制访问目标对象的过程。当我们在应用中使用AOP时,Spring会在运行时动态地创建一个代理对象,该代理对象包含了目标对象的所有方法,并且可以在目标对象的...
写文章

热门文章

  • JAVA复习:8进制与16进制 1687
  • 面试准备啊 1331
  • JAVA:JSP 931
  • MySQL:Maven 487
  • Java复习:泛型 434

分类专栏

  • JavaSe 20篇
  • JavaWeb阶段 1篇

最新评论

  • JAVA复习:8进制与16进制

    skr.~: 哈哈哈确实是写错了多谢指正

  • JAVA复习:8进制与16进制

    .苏北辰: 引用「(1*8^2+1*8^1+1*8^0)」 可以问下这串代表什么意思吗? (如果是八进制转换成十进制的话,是写错了吗?(小白,什么都不懂,在认真的表达自己的疑惑) [文章有帮到我,谢谢!]

最新文章

  • 面试准备啊
  • Mysql(锁)
  • Mysql(进阶)
2023年33篇
2022年76篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳SEO优化公司济南网站优化 鹊起科技宜宾网站运营优化公司网站推广优化怎么投放做个问答网站怎么优化宁波网站排名优化电话徐州网站优化可靠吗洛阳平台seo网站优化工具网站关键词推广优化培训重庆网站优化推广方案优化大流量网站湖南网站关键词优化排名技巧邛崃网站关键词优化视频排名优化网站连云港网站seo人工优化网站优化霸屏招商吉林价格低的珠宝行业网站优化普陀区正规网站服务商优化价格四会网站优化长期没有排名成都网站推广优化网址台州网站技术优化长春网站优化推广案例新邵网站优化来电咨询高新企业网站优化北仑区网站优化方式网站关键词优化如何做网站广告要多久才能优化优化型网站需要什么条件网站标题优化应注意的6个问题河南网站seo如何优化公司深圳关键词网站优化歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化