JDK dynamic proxy case and Principle Analysis

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 ; }

Guess you like

Origin www.cnblogs.com/itzhoucong/p/12143704.html