Spring AOP 代理简化详解

JDK代理CGLB代理

目标类是接口(/实现)类

或代理类

或启用GraalVM Native Image编译


默认为JDK代理时 实现类会使用默认配置JDK代理

重写代理接口

或默认为CGLB代理

或optimize标志已设置(增强化策略)

 

默认为CGLB代理时 实现类会使用默认配置CGLB代理

两者区别:
  • JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
  • CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
@Aspect 此注解创建代理的方式也是采用此方式

------此文对应下图观看
当默认为JDK代理时,如果目标类是实现类,此时默认ProxyTargetClass为false 此时无指定代理接口也无增强化会进入if{}中导致后续使用了JDK代理,后续如果不是接口类(此接收对象必须还要是实现类实现的接口类)接收此代理对象,则会抛出异常。
(问题原因:JDK代理只是接口代理,此时的代理对象是此实现类实现的接口类,JDK动态代理只提供接口的代理,不支持类的代理。) 
(解决方案:默认使用CGLB代理或使用此实现类实现的接口类接收此此代理对象--所以SpringBoot2.0开始默认使用CGLB代理防止此错误发生)。

当默认为CGLB代理时,如果目标类是实现类,此时默认ProxyTargetClass为true, 此时会进else{}中,经过判断此目标类不是接口类也不是代理类会使用CGLB代理。

NativeDetector--这个我照搬api上的,我不想了解它有点变态,有兴趣的伙伴可以自己去了解
用于检测GraalVM本机映像环境的公共委托。
需要使用本机映像编译器标志以允许在生成时删除代码 -H:+InlineBeforeAnalysis
inNativeImage()
如果在映像生成上下文中或在映像运行时期间调用,则返回true。否则false

ProxyTargetClass 使用默认配置 默认JDK代理则为false 默认CGLB代理为true,
(注意:此时默认为JDK代理时,当使用isProxyTargetClass()方法时会检测此目标类是否是接口类或代理类如不是则默认为false,反之会将其变为true---类验证检查)
配置:
Spring--XML
SpringBoot-注解

isOptimize()是否设置增强化策略(可配置---这个磨不透,也没往下磨有兴趣的可以全程跟踪源码走一次看看)
optimize用来标记是否需要对代理对象采取性能优化措施,默认值为false。
如果将optimize设置为true,那么在生成代理对象之后,如果对代理配置进行了修改,已经创建的代理对象也不会获取修改之后的代理配置。
使用Spring当前的代理选项,此标志有效地强制执行CGLIB代理(类似于setProxyTargetClass(布尔值)), 但没有任何类验证检查(对于最终方法等)。

hasNoUserSuppliedProxyInterfaces()是否指定代理接口
( 如果直接继承SpringProxy相关接口,重写里面的方法,那么就会采用默认自己写的代理方法,而不会使用SpringAop提供的方法)

使用与借鉴以下大佬文章内容:
Spring-Framework  API地址:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值