java的動態代理

Java的動態代理主要是指位於java.lang.reflect包下的Proxy類,在使用過程中會用到同一個包下的InvocationHandler接口。
 
1.Proxy類提供了個靜態方法Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) ,用來生成代理對象:
    loader是目標類的類加載器,
  interfaces是目標類實現的接口(並不一定是它實現的所有接口,用Class<?>[]類型表示就可以了),
  h是InvocationHandler類型的一個對象。
 
2.InvocationHandler接口提供類一個方法Object invoke(Object proxy,Method method,Object[] args) throws Throwable,用來調用目標方法並提供新的功能:
   proxy是代理對象,
   method是目標方法,
   args是目標方法的參數列表。
 
所謂動態代理其實就是這樣的一種對象:它是在程序運行時動態生成的對象,在生成它時你必須提供一組接口給它,然後該對象就宣稱它實現了這些接口。你當然可以把該對象當作這些接口中的任何一個來用。當然,這其實就是一個代理對象,它不會替你作實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
 
接口:
public interface StudentDao {
  public void test1();
  public void test2();
  public void test3();
  public void test4();
}

public interface StudentDao2 {
  public void t();
}
 
目標類:
public class StudentDaoImpl implements StudentDao ,StudentDao2{
    //對接口方法的實現
}
 
Handler:
public class MyInvocationHandler implements InvocationHandler {
  private Object target;
  private List<String> matchNames=null; //用來控制對目標類的那些方法做功能上的改變
  public MyInvocationHandler() {
  }
  public MyInvocationHandler(Object target) {
    this.target = target;
    matchNames=new ArrayList<String>();
    matchNames.add("test1");
    matchNames.add("test2");
    matchNames.add("test3");    
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String methodName=method.getName();
    if(matchNames.contains(methodName)){
      System.out.println("========begin transaction=========");
    }
    Object ret = method.invoke(target, args);
    if(matchNames.contains(methodName)){
      System.out.println("========end transaction==========");
    }
    return ret;
  }
}
 
測試類:
  public static void main(String[] args) {
    StudentDaoImpl dao=new StudentDaoImpl();
    MyInvocationHandler handler=new MyInvocationHandler(dao);
    StudentDao proxy=(StudentDao)Proxy.newProxyInstance(
                                        dao.getClass().getClassLoader(),
                                        new Class<?>[]{StudentDao.class},
                                        handler);
    proxy.test1();
    proxy.test2();
    proxy.test3();
    proxy.test4();
}
 
運行結果:
========begin transaction=========
==========目標方法:test1()============
========end transaction==========
========begin transaction=========
==========目標方法:test2()============
========end transaction==========
========begin transaction=========
==========目標方法:test3()============
========end transaction==========
==========目標方法:test4()============

 

本文出自 “夜狼” 博客,http://yangfei520.blog.51cto.com/1041581/245254

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章