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

原生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();
}
@Override
publicObjectintercept(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方法没有被代理。
为什么会有这样的差异?
                    
查看完整描述

2 回答

?
RISEBY
spring的aop无法拦截内部方法调用,spring会报存真实对象的bean以及代理后的proxyBean,proxyBean进行了切面增强处理:proxyBean相当于:
before
invoke(bean,method)
after这样处理就导致实际上fun2是实际的bean去调用的(invoke就是使用实际对象执行你要执行的方法),所以,没有before效果。而你实际使用cglib则全程都是用的是代理bean
                            
查看完整回答
反对 回复 2019-05-25
?
HUWWW
CGLib的原生写法那个代码,你把
publicvoidfun2(){
System.out.println("fun2");
}
改成
privatevoidfun2(){
System.out.println("fun2");
}
两者的运行就一样了
因为cglib的子类是增强类,增强类没继承fun2私有方法,所以fun1调的是父类的方法fun2,而不是增强类。
所以私有fun2没被拦截。
                            
查看完整回答
反对 回复 2019-05-25

添加回答

回复

举报

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