動態代理的手動實現

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/**
 * 代理模式的類型較多,不同類型的代理模式有不同的優缺點,它們應用於不同的場合:
 (1) 當客戶端對象需要訪問遠程主機中的對象時可以使用遠程代理。
 (2) 當需要用一個消耗資源較少的對象來代表一個消耗資源較多的對象,從而降低系統開銷、縮短運行時間時可以使用虛擬代理,例如一個對象需要很長時間才能完成加載時。
 (3) 當需要爲某一個被頻繁訪問的操作結果提供一個臨時存儲空間,以供多個客戶端共享訪問這些結果時可以使用緩衝代理。通過使用緩衝代理,系統無須在客戶端每一次訪問時都重新執行操作,只需直接從臨時緩衝區獲取操作結果即可。
 (4) 當需要控制對一個對象的訪問,爲不同用戶提供不同級別的訪問權限時可以使用保護代理。
 (5) 當需要爲一個對象的訪問(引用)提供一些額外的操作時可以使用智能引用代理。
 * 
 * 
 * 王宇龍 015729
 */




public class TestProxy {


/**事務管理對象*/
static class TransactionManager{
public void beginTransaction() {
System.out.println("begin transaction");
}
public void commitTransaction() {
System.out.println( "commit transaction");
}
}

public static void main(String[] args) {
TransactionManager transactionManager =new TransactionManager();
//1.創建目標對象
final TargetService target=new TargetServiceImpl();
//2.創建代理對象(動態代理)
TargetService proxy=(TargetService)
Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {//要擴展的業務,藉助此對象處理


@Override
public Object invoke(Object proxy, Method method, Object[] args) 
throws Throwable {
//獲取具體實現類中的方法,如無此步驟,則無法獲取實現類的註解,只有接口的
Method targetmethod = 
target.getClass()
.getDeclaredMethod(method.getName(), 
method.getParameterTypes());
if(targetmethod.isAnnotationPresent(Transaction.class)) {
//1.擴展功能
transactionManager.beginTransaction();
//2.核心業務
Object result=targetmethod.invoke(target, args);
//3.擴展功能
transactionManager.commitTransaction();
return result;
}
System.out.println("沒有註解");

return null;
}
});
//3.執行具體業務
proxy.saveObject();
}

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