JDK代理 |
CGLB代理 |
目标类是接口类或代理类
默认为JDK代理时 实现类会使用默认配置JDK代理 |
目标类无接口或无指定代理接口或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代理。
ProxyTargetClass 使用默认配置 默认JDK代理则为false 默认CGLB代理为true,
(注意:此时默认为JDK代理时,当使用isProxyTargetClass()方法时会检测此目标类是否是接口类或代理类如不是则默认为false,反之会将其变为true)
配置:
Spring--XML
SpringBoot-注解
isOptimize()是否设置增强化策略(可配置)
hasNoUserSuppliedProxyInterfaces()是否指定代理接口
( 如果直接继承SpringProxy相关接口,重写里面的方法,那么就会采用默认自己写的代理方法,而不会使用SpringAop提供的方法)
使用与借鉴以下大佬文章内容:
https://thinkwon.blog.csdn.net/article/details/104397516
https://blog.csdn.net/qq_43564410/article/details/118963041