cglib动态代理之MethodProxy
cglib动态代理的MethodProxy在优化方法调用的时候起了关键作用,下面是MethodProxy方法调用的实现,里面避免了使用反射调用。
1.目标类
package com.sf.contract.util.a17;public class Target {public void save(){System.out.println("save()");}public void save(int i){System.out.println("save(int)");}public void save(long j){System.out.println("save(long)");}
}
2.Proxy类
package com.sf.contract.util.a17;import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;public class Proxy extends Target{private MethodInterceptor interceptor;public void setInterceptor(MethodInterceptor interceptor){this.interceptor = interceptor;}static Method save0;static Method save1;static Method save2;static MethodProxy save0proxy;static MethodProxy save1proxy;static MethodProxy save2proxy;static {try {save0 = Target.class.getMethod("save");save1 = Target.class.getMethod("save", int.class);save2 = Target.class.getMethod("save", long.class);save0proxy = MethodProxy.create(Target.class, Proxy.class,"()V","save","saveSuper");save1proxy = MethodProxy.create(Target.class, Proxy.class,"(I)V","save","saveSuper");save2proxy = MethodProxy.create(Target.class, Proxy.class,"(J)V","save","saveSuper");} catch (NoSuchMethodException e) {throw new NoSuchMethodError(e.getMessage());}}//带原始功能的save方法public void saveSuper(){super.save();}public void saveSuper(int i){super.save(i);}public void saveSuper(long j){super.save(j);}//带增强功能的save方法@Overridepublic void save() {try {interceptor.intercept(this,save0,new Object[0],save0proxy);} catch (Throwable e) {throw new UndeclaredThrowableException(e);}}@Overridepublic void save(int i) {try {interceptor.intercept(this,save1,new Object[]{i},save1proxy);} catch (Throwable e) {throw new UndeclaredThrowableException(e);}}@Overridepublic void save(long j) {try {interceptor.intercept(this,save2,new Object[]{j},save2proxy);} catch (Throwable e) {throw new UndeclaredThrowableException(e);}}
}
相比之前的实现,新增三个原始的方法(调用父类的方法)。并在里面创建MethodProxy对象,通过interceptor传入供回调使用,以save0为例。
save0proxy = MethodProxy.create(Target.class, Proxy.class,"()V","save0","saveSuper");需要使用到四个参数,第一个是目标类,第二个是代理类,第三个是描述,()表示原始方法参数为空,V表示返回值为空,save是增强后的方法,saveSuper是原始的方法。
3.主类调用
package com.sf.contract.util.a17;import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class a17 {public static void main(String[] args) {Proxy proxy = new Proxy();Target target = new Target();proxy.setInterceptor(new MethodInterceptor() {@Overridepublic Object intercept(Object p, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("before...");/*Object invoke = method.invoke(target, objects);//反射调用return invoke;*/return methodProxy.invokeSuper(p,objects);//内部无反射,结合代理调用}});proxy.save();proxy.save(1);proxy.save(2L);}
}
1)使用methodProxy对象结合代理对象进行方法调用,里面没有用到反射。

2) 使用methodProxy对象结合目标对象进行方法调用,里面也没有用到反射。
package com.sf.contract.util.a17;import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class a17 {public static void main(String[] args) {Proxy proxy = new Proxy();Target target = new Target();proxy.setInterceptor(new MethodInterceptor() {@Overridepublic Object intercept(Object p, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("before...");/*Object invoke = method.invoke(target, objects);//反射调用return invoke;*//*return methodProxy.invokeSuper(p,objects);//内部无反射,结合代理调用*/return methodProxy.invoke(target,objects);//内部无反射,结合目标对象调用}});proxy.save();proxy.save(1);proxy.save(2L);}
}
输出结果:

