为何Spring为实现多接口的类创建CGLIB代理而非JDK动态代理?
Spring AOP用CGLIB而非JDK动态代理的原因分析
即使你的类X实现了接口A和B,Spring AOP仍然可能选择CGLIB代理,常见原因有这几个:
依赖注入时用了类类型而非接口类型
如果你的代码里是这么注入的:@Autowired private X x; // 用了类X作为注入类型而不是:
@Autowired private A x; // 用接口A作为注入类型JDK动态代理生成的代理类只是实现了A和B接口,不是X的子类,没法赋值给X类型的变量。这种情况下Spring会自动切换为CGLIB代理,生成X的子类代理,同时实现接口,这样既满足切面需求,又能适配类类型的注入。
显式开启了
proxy-target-class=true
如果你在配置里加了这个参数(不管是@EnableAspectJAutoProxy(proxyTargetClass = true)还是XML里的<aop:aspectj-autoproxy proxy-target-class="true"/>),Spring会强制使用CGLIB代理,完全忽略是否有接口存在。切面切入点或逻辑依赖类的非接口方法
哪怕你切入点是接口A的方法,但如果切面里用到了target(X)、this(X)这类表达式,或者需要调用X类自身的非接口方法,JDK代理也没法处理——因为JDK代理只能代理接口定义的方法,所以Spring会切换到CGLIB来代理整个类。Spring版本的默认行为变更
虽然多数版本里默认是有接口用JDK代理,但某些场景下(比如结合其他Spring特性),也可能触发默认用CGLIB的逻辑,不过这种情况比较少见,优先排查上面几个点。
内容的提问来源于stack exchange,提问作者sidmas_999
相关产品推荐
相关产品推荐

