標籤:
1.代理類可以分為兩種。
靜態代理:由程式員建立或特定工具自動產生原始碼,再對其編譯。在程式運行前,代理類的.class檔案就已經存在了。
動態代理:在程式運行時,運用反射機制動態建立而成。
2.JDK的動態代理依靠介面實現,如果有些類並沒有實現介面,則不能使用JDK代理,這就要使用cglib動態代理了。
3.Cglib動態代理
JDK的動態代理機制只能代理實現了介面的類,而不能實現介面的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類產生一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理。
4.
JDK動態代理中包含一個類和一個介面:
InvocationHandler介面:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參數說明:
Object proxy:指被代理的對象。
Method method:要調用的方法
Object[] args:方法調用時所需要的參數
可以將InvocationHandler介面的子類想象成一個代理的最終操作類,替換掉ProxySubject。
Proxy類:
Proxy類是專門完成代理的操作類,可以通過此類為一個或多個介面動態地產生實作類別,此類提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
參數說明:
ClassLoader loader:類載入器
Class<?>[] interfaces:得到全部的介面
InvocationHandler h:得到InvocationHandler介面的子類執行個體
Ps:類載入器
在Proxy類中的newProxyInstance()方法中需要一個ClassLoader類的執行個體,ClassLoader實際上對應的是類載入器,在Java中主要有一下三種類載入器;
Booststrap ClassLoader:此載入器採用C++編寫,一般開發中是看不到的;
Extendsion ClassLoader:用來進行擴充類的載入,一般對應的是jre\lib\ext目錄中的類;
AppClassLoader:(預設)載入classpath指定的類,是最常使用的是一種載入器。
動態代理
與靜態代理類對照的是動態代理類,動態代理類的位元組碼在程式運行時由Java反射機制動態產生,無需程式員手工編寫它的原始碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴充性,因為Java 反射機制可以產生任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了產生動態代理類的能力。
例如:
public interface OderFacade { public void addOrder(); }
public class OrderFacadeImpl implements OrderFacade { @Override public void addOrder() { System.out.println("增加訂單"); } }
/** * JDK動態代理代理類 * */ public class OrderFacadeProxy implements InvocationHandler { private Object target; /** * 綁定委派物件並返回一個代理類 * @param target * @return */ public Object bind(Object target) { this.target = target; //取得代理對象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); //要綁定介面(這是一個缺陷,cglib彌補了這一缺陷) } @Override /** * 調用方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; System.out.println("事物開始"); //執行方法 result=method.invoke(target, args); System.out.println("事物結束"); return result; } }
public class TestProxy { public static void main(String[] args) { OrderFacadeProxy proxy = new OrderFacadeProxy(); OrderFacade bookProxy = (OrderFacade) proxy.bind(new OrderFacadeImpl()); orderProxy.addOrder(); } }
java動態代理和cglib