JDK动态代理实现原理1.根据传入的类接口和InvocationHandler创建接口的代理类字节码文件。通过反射创建方法。方法就是接口中的方法,可以通过方法调用实现类重写的方法。2、使用ClassLoader将字节码文件加载到JVM中(定义了一个类,类似$Proxy0、$Proxy1等)3、反向创建代理类实例对象4、调用代理对象方法时,会在InvocationHandler的invoke方法中,这里是用户编写的代理逻辑。通过method.invoke调用代理对象的实现逻辑。通过反射生成方法,然后定义一个ProxyX类,再通过反射实例化这个类,生成代理对象。代理对象的方法会进入InvocationHandler的invoke方法ps:jdk代理只能代理接口中实现的类和equals、hashCode、toString方法。jdk代理不支持实现类的代理,只支持接口的代理,因为生成的类已经继承了Proxy,java不能继承更多。https://blog.csdn.net/mhmyqn/...cglib实现了agent的逻辑。1、首先我们通过Enhancer实例设置代理类。2、然后设置代理类的回调,也就是在访问代理类方法的时候,我们会先转向回调。3.回调中我们调用invokeSuper方法给fastclass非反射机制快速调用代理类中的方法,代理类中的方法调用原类型对应的方法。methodProxy.invokeSuper(Objectobj,Object[]args)-->根据方法名生成fastClassInfo,然后根据fastClassInfo中的下标信息直接调用fastClass的invoke方法。根据obj的类型,进入对应fastclass目标类的fastclassinvoke方法publicObjectinvoke(intvar1,Objectvar2,Object[]var3)throwsInvocationTargetException{//直接强制UserManagerImplvar10000=(UserManagerImpl)var2;intvar10001=var1;try{switch(var10001){案例0:var10000.delUser((String)var3[0]);返回空值;case1:......代理类的fastclass的invoke方法publicObjectinvoke(intvar1,Objectvar2,Object[]var3)throwsInvocationTargetException{326ab821var10000=(326ab821)var2;intvar10001=var1;try{switch(var10001){case0:returnnewBoolean(var10000.equals(var3[0]));1:……总结一下JDK动态代理和Gglib动态代理的区别:1.JDK动态代理实现了代理对象的接口,Cglib继承了代理对象。2、JDK和Cglib都是在运行时生成字节码。JDK直接写Class字节码,Cglib使用ASM框架写Class字节码。Cglib代理实现比较复杂,代理类的生成效率不如JDK。3、JDK通过反射机制调用代理方法,Cglib通过FastClass机制直接调用方法。Cglib具有更高的执行效率。注意:只有invokeSuper是fastClass机制,其余的invoke仍然使用反射https://www.cnblogs.com/monke...可以通过Enhancer生成代理类,将CallBack传入CallBack代码执行时的代码,以便执行用户定义的代码;用户自定义代码可以决定是调用目标类还是调用代理类调用目标类使用$$FastClass1调用代理类使用$$FastClass2调用$$FastClass调用时触发生成$$FastClassas动态生成类,通过索引和方法签名的一对一映射生成switchcase语句,提高调用效率。代理类是通过继承实现的,CGLIB代理不能用于final类和方法。所以CGLB代理调用效率高,但是生成效率慢,至少3个文件,1个代理类,2个FastClass类。所有生成的类都加载到JVM堆中。packageproxy;publicclassBigCarimplementsCar{@Overridepublicvoidstart(){System.out.println("bigcarstart");}publicvoidstart(inta){System.out.println("大车启动");}}包代理;公共接口车{voidstart();}包代理;导入net.sf.cglib.proxy.MethodInterceptor;导入net.sf.cglib.proxy.MethodProxy;导入java.lang.reflect.Method;public类CglibInvocationHandler实现MethodInterceptor{对象目标;publicObjectgetTarget(){返回目标;}publicvoidsetTarget(Objecttarget){this.target=target;}/**调用过程:代理对象调用this.被代理的方法->调用截器拦截->methodProxy.invokeSuper->CGLIB$setPerson$0->被代理对象setPerson方法publicObject*/@Override,Method方法,Object[]objects,MethodProxymethodProxy)throwsThrowable{System.out.println("cglibproxystart");//o是一个代理对象,methodProxy.invoke会调用o的方法,然后进入拦截方法,形成死循环Objectresult=methodProxy.invokeSuper(o,objects);//原生cglib可以实现内部方法代理,//spring的cglib实现aop不能切到内部调用的方法,除非专门设置//spring的aop的写法//spring会保存真正的bean目的//对象结果=methodProxy.invoke(target,objects);System.out.println("cglib代理结束");返回结果;}}包代理;导入net.sf.cglib.proxy.Callback;导入net.sf.cglib.proxy.Enhancer;publicclassCglibProxyFactory{publicstaticObjectcreateProxy(Classc,Callbackcallback){Enhancerenhancer=newEnhancer();enhancer.setSuperclass(c);enhancer.setCallback(回调);返回enhancer.create();}}packageproxy;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Proxy;publicclassJdkProxyFactory{publicstaticObjectgetJDKProxy(ObjecttargetObject,InvocationHandlerhandler){//JDK动态代理只能实现带有接口的类用于代理,newProxyInstance函数需要的参数可以看//根据接口类返回Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),处理程序);}}包代理;导入java.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;//JDK动态代理实现InvocationHandler接口publicclassJdkProxyInvocationHandlerimplementsInvocationHandler{privateObjecttarget;//需要代理的目标对象publicJdkProxyInvocationHandler(Objecttarget){this.target=target;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("JDK动态代理,监听开始!");System.out.println(proxy.getClass()+"111");对象结果=method.invoke(target,args);System.out.println("JDK动态代理,监听结束!");返回结果;}}包代理;importnet.sf.cglib.core.DebuggingClassWriter;importjava.lang.reflect.Method;publicclassTest{publicstaticvoidmain(String[]args){UserManagertarget=newUserManagerImpl();//JdkProxyInvocationHandlerhandler=newJdkProxyInvocationHandler(target);//UserManageruserManager=(UserMainnager)JdkProxyFactory.getJDKProxy(target,handler);//userManager.addUser("1","1");System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:\\Users\\YEZHENGWU839\\Desktop\\xiaoxi");CglibInvocationHandlerhandler1=newCglibInvocationHandler();handler1.setTarget(目标);UserManageruserManager2=(UserManager)CglibProxyFactory.createProxy(target.getClass(),handler1);userManager2.addUser("2","@");.out.println(userManager2.getClass().getName());}}packageproxy;publicinterfaceUserManager{//添加用户抽象方法voidaddUser(StringuserName,Stringpassword);//删除用户抽象方法voiddelUser(StringuserName);defaultvoidfind(){System.out.println("superinterfacefind");}}packageproxy;//用户管理实现类,实现用户管理接口publicclassUserManagerImplimplementsUserManager{//重写添加用户方法@OverridepublicvoidaddUser(StringuserName,Stringpassword){System.out.println("新方法已经调用!");System.out.println("传入参数为userName:"+userName+"password:"+password);delUser("111");}//重写删除用户方法@OverridepublicvoiddelUser(StringuserName){System.out.println("调用了删除方法!");System.out.println("传入参数为userName:"+userName);}//不是接口的类不能被委托publicvoidshow(){System.out.println("thisimplmethodnotsupermethod");}}
