A, JDK dynamic proxy implementation Case
Person Interface
Package com.zhoucong.proxy.jdk; public interface the Person { // True Love void findlove (); }
Character implementation class
Package Penalty for com.zhoucong.proxy.jdk; public class Zhangsan the implements the Person { @Override public void findlove () { System.out.println ( "I called Zhang three female gender, I find the object of the requirements are as follows: \ the n-" ); System.out.println ( "rich handsome" ); System.out.println ( "a house and a car" ); System.out.println ( "height above 180cm, weight 70kg" ); } }
Acting Class
Package com.zhoucong.proxy.jdk; Import java.lang.reflect.InvocationHandler; Import the java.lang.reflect.Method; Import the java.lang.reflect.Proxy; public class MeiPo the implements of InvocationHandler { Private the Person target; // acquires agent profile public object getInstance (the Person target) throws Exception { the this .target = target; Class clazz = target.getClass (); System.out.println ( "the proxy object class is:" + clazz); returnThe Proxy.newProxyInstance (clazz.getClassLoader (), clazz.getInterfaces (), the this ); } @Override public Object Invoke (Object the arg0, Method, Method, Object [] args) throws the Throwable { System.out.println ( "I matchmaker !! " ); System.out.println ( " start information audition ... " ); System.out.println ( " ------------- " ); Method.invoke ( the this .target, args); System.out.println ( "-------------" ); System.out.println ( "if appropriate, ready to work" ); return null ; } }
Run the test
Package com.zhoucong.proxy.jdk; public class TestFindLove { public static void main (String [] args) { the try { the Person obj = (the Person) new new MeiPo () the getInstance (. new new Zhangsan ()); System.out.println (obj.getClass ()); obj.findlove (); / ** * principle: * 1. get the referenced proxy object, and then get its interface * 2.jdk regenerate a proxy class, while achieving one of our amount implemented interface proxy object * 3. the proxy object reference is also got * 4. re-byte code class to dynamically generate a * 5 and then compile * / } the catch (Exception e) { e.printStackTrace(); } } }
operation result:
Key:
Acting before the object com.zhoucong.proxy.jdk.Zhangsan
After the proxy objects com.sun.proxy obtained. $ Proxy0
Second, the principle analysis
Gets $ Proxy0.class bytecode content
Package com.zhoucong.proxy.jdk; Import java.io.FileOutputStream; Import sun.misc.ProxyGenerator; public class TestFindLove { public static void main (String [] args) { the try { the Person obj = (the Person) new new MeiPo () .getInstance ( new new Zhangsan ()); System.out.println (obj.getClass ()); obj.findlove (); // Get the bytecode content // ProxyGenerator need to install jdk introduced rt directory jre / bin. JAR byte [] = generateProxyClass ProxyGenerator.generateProxyClass ( "$ Proxy0", new new Class[] { Person.class }); // 输出到本地 FileOutputStream os = new FileOutputStream("E:/GP_WORKSPACE/$Proxy0.class"); os.write(generateProxyClass); os.close(); } catch (Exception e) { e.printStackTrace(); } } }
Use Java decompiler tools are the following documents:
$ Proxy0.java
import com.zhoucong.proxy.jdk.Person; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements Person { private static Method m1; private static Method m2; private static Method m0; private static Method m3; public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } public final boolean equals(Object paramObject) { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error|RuntimeException error) { throw null; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString() { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException error) { throw null; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException error) { throw null; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void findlove() { try { this.h.invoke(this, m3, null); return; } catch (Error|RuntimeException error) { throw null; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("com.zhoucong.proxy.jdk.Person").getMethod("findlove", new Class[0]); return; } catch (NoSuchMethodException noSuchMethodException) { throw new NoSuchMethodError(noSuchMethodException.getMessage()); } catch (ClassNotFoundException classNotFoundException) { throw new NoClassDefFoundError(classNotFoundException.getMessage()); } } }
Points analysis:
Features: 1, JDK proxy-generated class implements the Person interface inherits the parent class Proxy
Analysis: JDK dynamic proxy must have interfaces (cglib no)
2, a method of obtaining a static block interface
m3 = Class.forName("com.zhoucong.proxy.jdk.Person").getMethod("findlove", new Class[0]);
3, JDK proxy-generated class implements the interface method, the important word written inside
this.h.invoke(this, m3, null);
Analysis: this.h to the parent class Proxy view that member variables of the parent class
/** * the invocation handler for this proxy instance. * @serial */ protected InvocationHandler h;
I.e. MeiPo class and calls the inside of the Object invoke (Object arg0, Method method, Object [] args) Method
@Override public Object the Invoke (Object arg0, Method, Method,, Object [] args) throws Throwable { System.out.println ( "I'm a matchmaker !!" ); System.out.println ( "start information audition ..." ); System.out.println ( "-------------" ); // this.target.findlove (); // can also be written as follows, the same effect
// implemented using the reflection
Method.invoke ( the this .target, args); System.out.println ( "-------------" ); System.out.println ( "if appropriate, ready to work." ) ; return null ; }