为了账号安全,请及时绑定邮箱和手机立即绑定

原生CGLib内部方法互相调用时可以代理,但基于CGLib的Spring AOP却代理失效,为什么?

原生CGLib内部方法互相调用时可以代理,但基于CGLib的Spring AOP却代理失效,为什么?

湖上湖 2019-05-25 18:04:32
下面是CGLib的原生写法(使用net.sf.cglib.proxy.*包内的类实现)classFoo{publicvoidfun1(){System.out.println("fun1");fun2();}publicvoidfun2(){System.out.println("fun2");}}classCGlibProxyEnhancerimplementsMethodInterceptor{publicObjectgetProxy(Classclazz){Enhancerenhancer=newEnhancer();enhancer.setSuperclass(clazz);enhancer.setCallback(this);returnenhancer.create();}@OverridepublicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{System.out.print("before");Objectresult=proxy.invokeSuper(obj,args);returnresult;}}publicclassTest{publicstaticvoidmain(String[]args){CGlibProxyEnhancerpf=newCGlibProxyEnhancer();Foofoo=(Foo)pf.getProxy(Foo.class);foo.fun1();}}打印结果是:beforefun1beforefun2可以看到,虽然fun2()是通过foo.fun1()调用的,但fun()2依然能被代理。但如果用SpringAOP那套基本写法的话:classFoo{publicvoidfun1(){System.out.println("fun1");fun2();}publicvoidfun2(){System.out.println("fun2");}}classBeforeimplementsMethodBeforeAdvice{publicvoidbefore(Methodmethod,Object[]objects,Objecto)throwsThrowable{System.out.print("before");}}publicclassTestCGLib{publicstaticvoidmain(String[]args){Foofoo=newFoo();BeforeAdviceadvice=newBefore();ProxyFactorypf=newProxyFactory();pf.setOptimize(true);//启用Cglib2AopProxy创建代理pf.setProxyTargetClass(true);pf.setTarget(foo);pf.addAdvice(advice);Fooproxy=(Foo)pf.getProxy();proxy.fun1();}}输出结果是:beforefun1fun2可见fun2方法没有被代理。为什么会有这样的差异?
查看完整描述

3 回答

?
qq_宁缺毋滥_17

TA贡献1条经验 获得超0个赞

invoke和invokeSuper的区别,spring-aop用的invoke

查看完整回答
反对 回复 2019-09-06
?
HUWWW

TA贡献1874条经验 获得超12个赞

CGLib的原生写法那个代码,你把
publicvoidfun2(){
System.out.println("fun2");
}
改成
privatevoidfun2(){
System.out.println("fun2");
}
两者的运行就一样了
因为cglib的子类是增强类,增强类没继承fun2私有方法,所以fun1调的是父类的方法fun2,而不是增强类。
所以私有fun2没被拦截。
                            
查看完整回答
反对 回复 2019-05-25
  • 3 回答
  • 0 关注
  • 2162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信