CGLIB 代理有哪些不能做的事?final 方法为什么读到 null?构造器会不会被调用两次?final 类能不能被代理?这篇在 Spring Framework 7.0.9 上逐项验证。
目标对象构造时 name="真名"。通过代理调用:
open()(普通 public 方法)→ open:真名 [切面拦截 1 次:[open]]
locked()(final 方法)→ locked:null [切面拦截 0 次]
callHidden()(public 方法,里面调 private hidden())→ hidden:真名 [切面拦截 1 次:[callHidden]]
static stat() → static [切面拦截 0 次]
Svc.ctor(构造器被调用的次数)= 1;Bean 是代理?truefinal 方法不被拦截且在代理自身上执行;private 和 static 方法不单独拦截。
有 public 无参构造器的 Plain,变成代理后构造器被调用了 1 次;isAopProxy = true;spring.objenesis.ignore = (没设) 有 public 无参构造器的 Plain,变成代理后构造器被调用了 2 次;isAopProxy = true;spring.objenesis.ignore = true
默认靠 Objenesis 不调用构造器,关掉后会调用两次。
只有带参构造器的 Svc 变成代理:成功,构造器被调用 1 次;spring.objenesis.ignore = (没设) LOG WARN AnnotationConfigApplicationContext: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'svc' defined in demo.Main$C1: Unexpected AOP exception 只有带参构造器的 Svc 变成代理:BeanCreationException ← NoSuchMethodException: demo.Main$Svc$$SpringCGLIB$$0.<init>()
能被代理是靠 Objenesis;关掉后找不到无参构造器就失败。
LOG WARN AnnotationConfigApplicationContext: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fin' defined in demo.Main$C3: Could not generate CGLIB subclass of class demo.Main$Fin: Common causes of this problem include using a final class or a non-visible class final 类 Fin 被切面匹配:BeanCreationException ← IllegalArgumentException: Cannot subclass final class demo.Main$Fin
不能继承,无法代理。