1 jdk动态代理
jdk动态代理限制:只能对实现了某一个接口的类进行代理。
原理:生成的代理类也实现了被代理类实现的接口,并且继承了Proxy类
jdk提供动态代理的工具:接口:java.lang.reflect.InvocationHandler, java.lang.reflect.Proxy;
实现jdk动态代理步骤:
首先定义被代理的类及被代理类实现的接口:
interface Movable { public void move(); } class Car implements Movable { public void move () { System.out.println("car is moving..."); } }
定义自己的InvocationHandler
abstract class CarInvocationHandler implements InvocationHandler { private Movable movable; CarInvocationHandler(Movable movable) { this.movable = movable; } public Movable getProxyInstance() { return (Movable)Proxy.newProxyInstance(Movable.class.getClassLoader(), new Class[]{Movable.class}, this); } public Class getProxyClass() { return Proxy.getProxyClass(Movable.class.getClassLoader(), new Class[]{}); } @Override public abstract Object invoke(Object proxy, Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException; public Movable getMovalbe() { return this.movable; } } class CarTimeInvocationHandler extends CarInvocationHandler { CarTimeInvocationHandler(Movable movable) { super(movable); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { System.out.println("startTime: " + System.currentTimeMillis()); Object result = method.invoke(this.getMovalbe(), args); System.out.println("end: " + System.currentTimeMillis()); return result; } }
实现InvocationHandler时,进行了少量封装,方便实现多种代理的InvocationHandler
获取代理类:调用invocationHanlder的getProxyInstance()方法;想要获取代理类的类可以调用getProxyClass()方法
jdk动态代理原理:
Proxy.newProxyInstance()源码为
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } }
由上图源码可知:Proxy首先获取到被代理类的class:Class cl = getProxyClass(loader, interfaces); 然后根据Class得到代理类的构造函数,然后根据构造函数生成代理类示例,也就是使用了反射。
那么Proxy怎么获取代理类的Class呢?下面是Proxy getProxyClass主要源码:
private byte[] generateClassFile() { /* ============================================================ * Step 1: Assemble ProxyMethod objects for all methods to * generate proxy dispatching code for. */ /* * Record that proxy methods are needed for the hashCode, equals, * and toString methods of java.lang.Object. This is done before * the methods from the proxy interfaces so that the methods from * java.lang.Object take precedence over duplicate methods in the * proxy interfaces. */ addProxyMethod(hashCodeMethod, Object.class); addProxyMethod(equalsMethod, Object.class); addProxyMethod(toStringMethod, Object.class); /* * Now record all of the methods from the proxy interfaces, giving * earlier interfaces precedence over later ones with duplicate * methods. */ for (int i = 0; i < interfaces.length; i++) { Method[] methods = interfaces[i].getMethods(); for (int j = 0; j < methods.length; j++) { addProxyMethod(methods[j], interfaces[i]); } } /* * For each set of proxy methods with the same signature, * verify that the methods' return types are compatible. */ for (List<ProxyMethod> sigmethods : proxyMethods.values()) { checkReturnTypes(sigmethods); } /* ============================================================ * Step 2: Assemble FieldInfo and MethodInfo structs for all of * fields and methods in the class we are generating. */ try { methods.add(generateConstructor()); for (List<ProxyMethod> sigmethods : proxyMethods.values()) { for (ProxyMethod pm : sigmethods) { // add static field for method's Method object fields.add(new FieldInfo(pm.methodFieldName, "Ljava/lang/reflect/Method;", ACC_PRIVATE | ACC_STATIC)); // generate code for proxy method and add it methods.add(pm.generateMethod()); } } methods.add(generateStaticInitializer()); } catch (IOException e) { throw new InternalError("unexpected I/O Exception"); } if (methods.size() > 65535) { throw new IllegalArgumentException("method limit exceeded"); } if (fields.size() > 65535) { throw new IllegalArgumentException("field limit exceeded"); } /* ============================================================ * Step 3: Write the final class file. */ /* * Make sure that constant pool indexes are reserved for the * following items before starting to write the final class file. */ cp.getClass(dotToSlash(className)); cp.getClass(superclassName); for (int i = 0; i < interfaces.length; i++) { cp.getClass(dotToSlash(interfaces[i].getName())); } /* * Disallow new constant pool additions beyond this point, since * we are about to write the final constant pool table. */ cp.setReadOnly(); ByteArrayOutputStream bout = new ByteArrayOutputStream(); DataOutputStream dout = new DataOutputStream(bout); try { /* * Write all the items of the "ClassFile" structure. * See JVMS section 4.1. */ // u4 magic; dout.writeInt(0xCAFEBABE); // u2 minor_version; dout.writeShort(CLASSFILE_MINOR_VERSION); // u2 major_version; dout.writeShort(CLASSFILE_MAJOR_VERSION); cp.write(dout); // (write constant pool) // u2 access_flags; dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER); // u2 this_class; dout.writeShort(cp.getClass(dotToSlash(className))); // u2 super_class; dout.writeShort(cp.getClass(superclassName)); // u2 interfaces_count; dout.writeShort(interfaces.length); // u2 interfaces[interfaces_count]; for (int i = 0; i < interfaces.length; i++) { dout.writeShort(cp.getClass( dotToSlash(interfaces[i].getName()))); } // u2 fields_count; dout.writeShort(fields.size()); // field_info fields[fields_count]; for (FieldInfo f : fields) { f.write(dout); } // u2 methods_count; dout.writeShort(methods.size()); // method_info methods[methods_count]; for (MethodInfo m : methods) { m.write(dout); } // u2 attributes_count; dout.writeShort(0); // (no ClassFile attributes for proxy classes) } catch (IOException e) { throw new InternalError("unexpected I/O Exception"); } return bout.toByteArray(); }
由上可知:首先生成成员变量,代理方法,然后做一定的检查,然后返回字节码。
以下是生成代理类的代码:
import com.malone.proxy.Movable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class Proxy11 extends Proxy implements Movable { private static Method m1; private static Method m3; private static Method m0; private static Method m2; public Proxy11(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void move() throws { try { this.h.invoke(this, m3, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() throws { try { return ((String)this.h.invoke(this, m2, null)); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m3 = Class.forName("com.malone.proxy.Movable").getMethod("move", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }
由生成代理类的代码可知,代理类实现了被代理类实现的接口,继承了Proxy类,代理类的构造函数会把参赛handler赋给Proxy类的handler,根据代理类创建代理类对象时,
Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h });
Proxy.newInstance()方法中传递的handler传递到代理类的构造函数里,及赋给了Proxy的handler。
当代理类调用equals,hashCode, toString,和代理类实现接口中的方法时,实际上执行的是自己定义的invocationHanlder的invoke方法。
jdk生成代理时,我们很难找到代理类的class文件
利用下面一个工具方法可以指定生成class文件路径:
class ProxyGeneratorUtils { /** * 把代理类的字节码写到硬盘上 * @param path 保存路径 */ public static void writeProxyClassToHardDisk(String path) { // 第一种方法,这种方式在刚才分析ProxyGenerator时已经知道了 // System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", true); // 第二种方法 // 获取代理类的字节码 byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy11", Car.class.getInterfaces()); FileOutputStream out = null; try { out = new FileOutputStream(path); out.write(classFile); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
二 cglib动态代理
限制:cglib不能代理类的final方法
原理:cglib通过操作asm,给被代理类生成子类
和jdk动态代理比较:不需要实现接口
cglib生成动态代理类的主要代码:
//被代理类 class TargetClass { public void create() { System.out.println("create method..."); } public void update() { System.out.println("update method..."); } }代理实现类
class CglibProxy implements MethodInterceptor { private Enhancer enhance = new Enhancer(); public Object getProxyInstance(Class<TargetClass> clazz) { enhance.setSuperclass(clazz); enhance.setCallback(this); enhance.setCallbackFilter(new MyCallbackFilter()); enhance.setCallbacks(new Callback[]{new CglibProxy(), new MyFixedValue()}); return enhance.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("prefix operate..."); Object result = proxy.invokeSuper(obj, args); System.out.println("after operate..."); return result; } }
生成代理类代码:
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2013/10/24 11:19:09 // Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version! // Decompiler options: packimports(3) // Source File Name: <generated> package com.malone.proxy; import java.lang.reflect.Method; import net.sf.cglib.core.Signature; import net.sf.cglib.proxy.*; // Referenced classes of package com.malone.proxy: // TargetClass public class TargetClass$$EnhancerByCGLIB$$a0f953e6 extends TargetClass implements Factory { static void CGLIB$STATICHOOK1() { Class class1; ClassLoader classloader; CGLIB$THREAD_CALLBACKS = new ThreadLocal(); classloader = (class1 = Class.forName("com.malone.proxy.TargetClass$$EnhancerByCGLIB$$a0f953e6")).getClassLoader(); classloader; CGLIB$emptyArgs = new Object[0]; CGLIB$create$0$Proxy = MethodProxy.create(classloader, (CGLIB$create$0$Method = Class.forName("com.malone.proxy.TargetClass").getDeclaredMethod("create", new Class[0])).getDeclaringClass(), class1, "()V", "create", "CGLIB$create$0"); CGLIB$update$1$Proxy = MethodProxy.create(classloader, (CGLIB$update$1$Method = Class.forName("com.malone.proxy.TargetClass").getDeclaredMethod("update", new Class[0])).getDeclaringClass(), class1, "()V", "update", "CGLIB$update$1"); CGLIB$finalize$2$Proxy = MethodProxy.create(classloader, (CGLIB$finalize$2$Method = Class.forName("java.lang.Object").getDeclaredMethod("finalize", new Class[0])).getDeclaringClass(), class1, "()V", "finalize", "CGLIB$finalize$2"); CGLIB$hashCode$3$Proxy = MethodProxy.create(classloader, (CGLIB$hashCode$3$Method = Class.forName("java.lang.Object").getDeclaredMethod("hashCode", new Class[0])).getDeclaringClass(), class1, "()I", "hashCode", "CGLIB$hashCode$3"); CGLIB$clone$4$Proxy = MethodProxy.create(classloader, (CGLIB$clone$4$Method = Class.forName("java.lang.Object").getDeclaredMethod("clone", new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4"); CGLIB$equals$5$Proxy = MethodProxy.create(classloader, (CGLIB$equals$5$Method = Class.forName("java.lang.Object").getDeclaredMethod("equals", new Class[] { Class.forName("java.lang.Object") })).getDeclaringClass(), class1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$5"); CGLIB$toString$6$Proxy = MethodProxy.create(classloader, (CGLIB$toString$6$Method = Class.forName("java.lang.Object").getDeclaredMethod("toString", new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/String;", "toString", "CGLIB$toString$6"); return; } final void CGLIB$create$0() { super.create(); } public final void create() { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 37; goto _L3 _L4 _L3: break MISSING_BLOCK_LABEL_21; _L4: break MISSING_BLOCK_LABEL_37; this; CGLIB$create$0$Method; CGLIB$emptyArgs; CGLIB$create$0$Proxy; intercept(); return; super.create(); return; } final void CGLIB$update$1() { super.update(); } public final void update() { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 37; goto _L3 _L4 _L3: break MISSING_BLOCK_LABEL_21; _L4: break MISSING_BLOCK_LABEL_37; this; CGLIB$update$1$Method; CGLIB$emptyArgs; CGLIB$update$1$Proxy; intercept(); return; super.update(); return; } final void CGLIB$finalize$2() throws Throwable { super.finalize(); } protected final void finalize() throws Throwable { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 37; goto _L3 _L4 _L3: break MISSING_BLOCK_LABEL_21; _L4: break MISSING_BLOCK_LABEL_37; this; CGLIB$finalize$2$Method; CGLIB$emptyArgs; CGLIB$finalize$2$Proxy; intercept(); return; super.finalize(); return; } final int CGLIB$hashCode$3() { return super.hashCode(); } public final int hashCode() { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 52; goto _L3 _L4 _L3: this; CGLIB$hashCode$3$Method; CGLIB$emptyArgs; CGLIB$hashCode$3$Proxy; intercept(); JVM INSTR dup ; JVM INSTR ifnonnull 45; goto _L5 _L6 _L5: JVM INSTR pop ; 0; goto _L7 _L6: (Number); intValue(); _L7: return; _L4: return super.hashCode(); } final Object CGLIB$clone$4() throws CloneNotSupportedException { return super.clone(); } protected final Object clone() throws CloneNotSupportedException { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 37; goto _L3 _L4 _L3: this; CGLIB$clone$4$Method; CGLIB$emptyArgs; CGLIB$clone$4$Proxy; intercept(); return; _L4: return super.clone(); } final boolean CGLIB$equals$5(Object obj) { return super.equals(obj); } public final boolean equals(Object obj) { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 57; goto _L3 _L4 _L3: this; CGLIB$equals$5$Method; new Object[] { obj }; CGLIB$equals$5$Proxy; intercept(); JVM INSTR dup ; JVM INSTR ifnonnull 50; goto _L5 _L6 _L5: JVM INSTR pop ; false; goto _L7 _L6: (Boolean); booleanValue(); _L7: return; _L4: return super.equals(obj); } final String CGLIB$toString$6() { return super.toString(); } public final String toString() { CGLIB$CALLBACK_0; if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1 _L1: JVM INSTR pop ; CGLIB$BIND_CALLBACKS(this); CGLIB$CALLBACK_0; _L2: JVM INSTR dup ; JVM INSTR ifnull 40; goto _L3 _L4 _L3: this; CGLIB$toString$6$Method; CGLIB$emptyArgs; CGLIB$toString$6$Proxy; intercept(); (String); return; _L4: return super.toString(); } public static MethodProxy CGLIB$findMethodProxy(Signature signature) { String s = signature.toString(); s; s.hashCode(); JVM INSTR lookupswitch 7: default 160 // -1949253108: 76 // -1574182249: 88 // -508378822: 100 // 598313209: 112 // 1826985398: 124 // 1913648695: 136 // 1984935277: 148; goto _L1 _L2 _L3 _L4 _L5 _L6 _L7 _L8 _L2: "update()V"; equals(); JVM INSTR ifeq 161; goto _L9 _L10 _L10: break MISSING_BLOCK_LABEL_161; _L9: return CGLIB$update$1$Proxy; _L3: "finalize()V"; equals(); JVM INSTR ifeq 161; goto _L11 _L12 _L12: break MISSING_BLOCK_LABEL_161; _L11: return CGLIB$finalize$2$Proxy; _L4: "clone()Ljava/lang/Object;"; equals(); JVM INSTR ifeq 161; goto _L13 _L14 _L14: break MISSING_BLOCK_LABEL_161; _L13: return CGLIB$clone$4$Proxy; _L5: "create()V"; equals(); JVM INSTR ifeq 161; goto _L15 _L16 _L16: break MISSING_BLOCK_LABEL_161; _L15: return CGLIB$create$0$Proxy; _L6: "equals(Ljava/lang/Object;)Z"; equals(); JVM INSTR ifeq 161; goto _L17 _L18 _L18: break MISSING_BLOCK_LABEL_161; _L17: return CGLIB$equals$5$Proxy; _L7: "toString()Ljava/lang/String;"; equals(); JVM INSTR ifeq 161; goto _L19 _L20 _L20: break MISSING_BLOCK_LABEL_161; _L19: return CGLIB$toString$6$Proxy; _L8: "hashCode()I"; equals(); JVM INSTR ifeq 161; goto _L21 _L22 _L22: break MISSING_BLOCK_LABEL_161; _L21: return CGLIB$hashCode$3$Proxy; _L1: JVM INSTR pop ; return null; } public static void CGLIB$SET_THREAD_CALLBACKS(Callback acallback[]) { CGLIB$THREAD_CALLBACKS.set(acallback); } public static void CGLIB$SET_STATIC_CALLBACKS(Callback acallback[]) { CGLIB$STATIC_CALLBACKS = acallback; } private static final void CGLIB$BIND_CALLBACKS(Object obj) { TargetClass$$EnhancerByCGLIB$$a0f953e6 targetclass$$enhancerbycglib$$a0f953e6 = (TargetClass$$EnhancerByCGLIB$$a0f953e6)obj; if(targetclass$$enhancerbycglib$$a0f953e6.CGLIB$BOUND) goto _L2; else goto _L1 _L1: Object obj1; targetclass$$enhancerbycglib$$a0f953e6.CGLIB$BOUND = true; obj1 = CGLIB$THREAD_CALLBACKS.get(); obj1; if(obj1 != null) goto _L4; else goto _L3 _L3: JVM INSTR pop ; CGLIB$STATIC_CALLBACKS; if(CGLIB$STATIC_CALLBACKS != null) goto _L4; else goto _L5 _L5: JVM INSTR pop ; goto _L2 _L4: (Callback[]); targetclass$$enhancerbycglib$$a0f953e6; JVM INSTR swap ; 0; JVM INSTR aaload ; (MethodInterceptor); CGLIB$CALLBACK_0; _L2: } public Object newInstance(Callback acallback[]) { CGLIB$SET_THREAD_CALLBACKS(acallback); CGLIB$SET_THREAD_CALLBACKS(null); return new TargetClass$$EnhancerByCGLIB$$a0f953e6(); } public Object newInstance(Callback callback) { CGLIB$SET_THREAD_CALLBACKS(new Callback[] { callback }); CGLIB$SET_THREAD_CALLBACKS(null); return new TargetClass$$EnhancerByCGLIB$$a0f953e6(); } public Object newInstance(Class aclass[], Object aobj[], Callback acallback[]) { CGLIB$SET_THREAD_CALLBACKS(acallback); JVM INSTR new #2 <Class TargetClass$$EnhancerByCGLIB$$a0f953e6>; JVM INSTR dup ; aclass; aclass.length; JVM INSTR tableswitch 0 0: default 35 // 0 28; goto _L1 _L2 _L2: JVM INSTR pop ; TargetClass$$EnhancerByCGLIB$$a0f953e6(); goto _L3 _L1: JVM INSTR pop ; throw new IllegalArgumentException("Constructor not found"); _L3: CGLIB$SET_THREAD_CALLBACKS(null); return; } public Callback getCallback(int i) { CGLIB$BIND_CALLBACKS(this); this; i; JVM INSTR tableswitch 0 0: default 30 // 0 24; goto _L1 _L2 _L2: CGLIB$CALLBACK_0; goto _L3 _L1: JVM INSTR pop ; null; _L3: return; } public void setCallback(int i, Callback callback) { this; callback; i; JVM INSTR tableswitch 0 0: default 29 // 0 20; goto _L1 _L2 _L2: (MethodInterceptor); CGLIB$CALLBACK_0; goto _L3 _L1: JVM INSTR pop2 ; _L3: } public Callback[] getCallbacks() { CGLIB$BIND_CALLBACKS(this); this; return (new Callback[] { CGLIB$CALLBACK_0 }); } public void setCallbacks(Callback acallback[]) { this; acallback; JVM INSTR dup2 ; 0; JVM INSTR aaload ; (MethodInterceptor); CGLIB$CALLBACK_0; } private boolean CGLIB$BOUND; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback CGLIB$STATIC_CALLBACKS[]; private MethodInterceptor CGLIB$CALLBACK_0; private static final Method CGLIB$create$0$Method; private static final MethodProxy CGLIB$create$0$Proxy; private static final Object CGLIB$emptyArgs[]; private static final Method CGLIB$update$1$Method; private static final MethodProxy CGLIB$update$1$Proxy; private static final Method CGLIB$finalize$2$Method; private static final MethodProxy CGLIB$finalize$2$Proxy; private static final Method CGLIB$hashCode$3$Method; private static final MethodProxy CGLIB$hashCode$3$Proxy; private static final Method CGLIB$clone$4$Method; private static final MethodProxy CGLIB$clone$4$Proxy; private static final Method CGLIB$equals$5$Method; private static final MethodProxy CGLIB$equals$5$Proxy; private static final Method CGLIB$toString$6$Method; private static final MethodProxy CGLIB$toString$6$Proxy; static { CGLIB$STATICHOOK1(); } public TargetClass$$EnhancerByCGLIB$$a0f953e6() { CGLIB$BIND_CALLBACKS(this); } }
看了这个反编译的代码不要凌乱啊
目前对cglib生成代理类研究不深,先在此记录如何使用cglib生成代理类;
cglib动态代理还有一个方面比jdk动态代理强大的地方就是:cglib允许为代理类的不同方法实现不同的代理
逻辑,实现代码如下:
public Object getProxyInstance(Class<TargetClass> clazz) { enhance.setSuperclass(clazz); // enhance.setCallback(this); enhance.setCallbackFilter(new MyCallbackFilter());//给代理类设置callBackFilter enhance.setCallbacks(new Callback[]{new MyLazyLoader(), new MyFixedValue()});//设置对应的filter数组 return enhance.create(); } class MyCallbackFilter implements CallbackFilter { public int accept(Method method) { if ("create".equals(method.getName())) { return 0;//返回数字为代理类callBack数组的下标值,下标值对应的callBack就是代理类该方法使用的CallBack } else if ("update".equals(method.getName())) { return 1; } return 0; } public boolean equals(Object o) { return false; } }
代理类可以设置一个CallBackFilter和一个CallBack数组,在CallBackFilter里定义每个方法使用CallBack数组里的CallBack,在对应的CallBack里定义方法的具体代理逻辑。
jdk的动态代理无法实现上述功能。
相关推荐
Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...
本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中的选择。 首先,JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类用于创建一个代理对象...
- **CGLIB代理**适用于目标类没有接口或者不希望修改原有接口的情况,其性能通常优于JDK代理,因为它是基于字节码生成的子类,而JDK代理需要反射调用接口方法。 在实际开发中,如Spring AOP框架就同时支持JDK和...
Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...
jdk和cglib动态代理的例子{jar包+源码} 解压:如有问题 用快压
- **CGLIB代理**:CGLIB通过ASM生成一个继承自目标类的新类,这个新类覆盖了目标类的所有方法,并在这些方法内部调用拦截器链。在运行时,这个新类的实例作为代理对象。 5. **优缺点**: - JDK代理简单易用,但...
本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...
本资源提供的示例涵盖了这些核心概念,通过JDK动态代理、CGLIB动态代理以及拦截器链的实践,帮助开发者深入理解并掌握这些技术。 首先,让我们来探讨JDK动态代理。Java标准库中的`java.lang.reflect.Proxy`类和`...
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...
jdk 的动态代理和CGLIB代理
JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...
2. CGLib代理项目: - src/main/java:包含目标类 - target/classes:编译后的class文件,包括目标类的class文件,以及由CGLib生成的子类class文件 - 测试代码:展示如何使用Enhancer创建代理对象并调用方法 这...
JDK动态代理和CGlib动态代理是Java中实现这一目标的两种主要方式。 ### JDK动态代理 JDK动态代理基于Java的接口实现。如果一个类实现了至少一个接口,我们就可以为这个类创建一个动态代理。动态代理通过`java.lang....
本篇将详细探讨JDK动态代理和Cglib动态代理,并通过源码实例来加深理解。 首先,JDK动态代理是Java内置的一种机制,它依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类...
与JDK的动态代理不同,JDK代理基于接口,如果目标类没有实现接口,就无法使用JDK的动态代理。而CGlib则无需目标类实现任何接口,因此它的应用范围更广。 以下是使用CGlib实现动态代理的关键步骤: 1. 引入依赖:在...
Cglib 动态代理的实现方式是:我们首先需要定义一个类,然后使用 Cglib 库来生成该类的代理对象,该代理对象将拦截对被代理对象的所有方法调用,并控制对被代理对象的访问。 Cglib 动态代理的优点是:它的实现方式...
JDK和CGlib是两种常用的动态代理实现方式,它们各自有不同的特性和使用场景。 首先,我们来详细了解一下JDK动态代理。JDK动态代理基于接口实现,它要求被代理的对象必须实现至少一个接口。通过`java.lang.reflect....
在Java中,代理模式有多种实现方式,包括静态代理、JDK动态代理和CGLIB动态代理。 **静态代理** 静态代理是最早也是最基础的代理实现方式。在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)...
CGLIB和JDK动态代理是两种常用的实现方式,它们各有优缺点,适用于不同的场景。下面将详细探讨这两种动态代理的区别。 首先,JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect....
Java提供了两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。 **JDK动态代理**: JDK动态代理基于接口实现,也就是说,被代理的对象必须实现至少一个接口。代理机制的核心是`java.lang.reflect.Proxy`类和...