Java类似CGLIB代理场景下父类为何不调用子类重写方法
问题根本原因
你当前实现的代理逻辑和真实CGLIB代理逻辑存在核心差异,问题本质是方法内部调用时this的指向问题:
1. 现有代码的执行流程拆解
你调用ChildService实例的callBoth()方法后:
- 第一步输出
ChildService.callBoth()符合预期 - 后续你调用的是
parentService.callBoth(),这里的parentService是ParentService的原生实例,不是代理对象 - 执行
parentService.callBoth()内部的method1()、method2()时,Java默认会用this.method1()、this.method2()触发调用,此处this指向的是原生ParentService实例本身,不是外层的ChildService代理实例,因此不会触发子类重写的方法实现,直接执行ParentService自带的逻辑。
2. 和真实CGLIB代理的差异
真实CGLIB代理不会持有原生目标对象再转发调用,而是通过继承父类后重写方法,增强逻辑执行完成后直接用super.xxx()调用父类的原生实现,此时方法内部的this指向的是代理对象本身,内部调用的方法就会触发代理的增强逻辑。
符合CGLIB逻辑的修正示例
你把ChildService改成如下写法,就能得到你预期的触发子类实现的效果:
public class ChildService extends ParentService { @Override public void method1() { System.out.println("ChildService.method1()"); super.method1(); } @Override public void method2() { System.out.println("ChildService.method2()"); super.method2(); } @Override public void callBoth() { System.out.println("ChildService.callBoth()"); super.callBoth(); } }
运行后输出结果为:
ChildService.callBoth() ParentService.callBoth() ChildService.method1() ParentService.method1() ChildService.method2() ParentService.method2()
内容的提问来源于stack exchange,提问作者artyom.poteshkin98
相关产品推荐
相关产品推荐

