教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Java培訓(xùn)實(shí)戰(zhàn)教程之將代理對(duì)象保存到本地文件

更新時(shí)間:2015年12月29日13時(shí)36分 來(lái)源:傳智播客Java培訓(xùn)學(xué)院 瀏覽次數(shù):

 
       我們知道,在Java中,常用的動(dòng)態(tài)代理技術(shù)有JDK的動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理,但是不管是哪種方式,代理對(duì)象都是在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成,而我們并不能直觀的看到生成的代理對(duì)象對(duì)應(yīng)的Java源代碼。下面,我就提供一種方式,可以將通過動(dòng)態(tài)代理創(chuàng)建的代理對(duì)象的字節(jié)碼文件保存到磁盤,再通過反編譯工具查看生成文件的內(nèi)容,這樣就可以加深我們對(duì)于代理對(duì)象的理解。
       JDK的動(dòng)態(tài)代理依靠接口實(shí)現(xiàn),如果有些類并沒有實(shí)現(xiàn)接口,則不能使用JDK代理,這就要使用cglib動(dòng)態(tài)代理了,在此,我們以JDK的動(dòng)態(tài)代理為例。
       在JDK中提供了一個(gè)ProxyGenerator類,可以將代理對(duì)象的字節(jié)碼得到,我們?cè)偻ㄟ^一個(gè)輸出流就可以將文件保存到磁盤了。
 
首先定義一個(gè)接口:
package cn.itcast.jdkproxy;
public interface IUserDao {
    public void save();
}
 
針對(duì)上面接口提供一個(gè)實(shí)現(xiàn)類:
package cn.itcast.jdkproxy;
public class UserDaoImpl implements IUserDao{
    public void save() {
       System.out.println("完成保存操作");
    }
}
 
通過JDK動(dòng)態(tài)代理技術(shù)創(chuàng)建代理對(duì)象:
package cn.itcast.jdkproxy;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import sun.misc.ProxyGenerator;
public class JdkProxyTest {
    public static void main(String[] args) throws Exception {
       final IUserDao target = new UserDaoImpl();
       IUserDao proxy = (IUserDao) Proxy.newProxyInstance(target.getClass()
              .getClassLoader(), target.getClass().getInterfaces(),
              new InvocationHandler() {
                  public Object invoke(Object proxy, Method method,
                         Object[] args) throws Throwable {
                     System.out.println(method.getName());
                     return method.invoke(target, args);
                  }
              });
       byte[] proxyClass = ProxyGenerator.generateProxyClass(proxy.getClass()
              .getSimpleName(), proxy.getClass().getInterfaces());
        //將字節(jié)碼文件保存到D盤,文件名為$Proxy0.class
       FileOutputStream outputStream = new FileOutputStream(new File(
              "d:\\$Proxy0.class"));
       outputStream.write(proxyClass);
       outputStream.flush();
       outputStream.close();
    }
}
 
通過反編譯工具可以查看生成的字節(jié)碼文件的內(nèi)容:
import cn.itcast.jdkproxy.IUserDao;
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 IUserDao
{
  private static Method m3;
  private static Method m1;
  private static Method m0;
  private static Method m2;
 
  public $Proxy0(InvocationHandler paramInvocationHandler)
    throws
  {
    super(paramInvocationHandler);
  }
 
  public final void save()
    throws
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
    }
    throw new UndeclaredThrowableException(localThrowable);
  }
 
  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 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
    {
      m3 = Class.forName("cn.itcast.jdkproxy.IUserDao").getMethod("save", new Class[0]);
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      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());
  }
}

 
 本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://metathetuscanyresort.com/javaee 
0 分享到:
和我們?cè)诰€交談!