JD設計模式之——動態代理
阿新 • • 發佈:2018-06-17
每次 kkk getclass throwable ace his login target pro
動態代理的目的就是,用代理類 來幫助被代理類處理一些邏輯
1.首先我們寫一個被代理類(因為代理都是面向接口編程 先來寫一個接口)
package javaee.net.cn.proxy; /** * 需要動態代理的接口 */ public interface Subject{ public void save(); }
2.在寫一個實現類(實際被代理的對象)
package javaee.net.cn.proxy; /** * 實際對象 */ public class RealSubject implements Subject{ public voidsave(){ System.out.println("insert into ......"); } }
3. LogInterceptor 通過實現接口 InvocationHandler 來代理實例
每個代理實例都具有一個關聯的調用處理程序。對代理實例調用方法時,將對方法調用進行編碼並將其指派到它的調用處理程序的 invoke
方法。(參考API)
package javaee.net.cn.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/** * 調用處理器實現類 * 每次生成動態代理類對象時都需要指定一個實現了該接口的調用處理器對象 */ public class LogInterceptor implements InvocationHandler{ /** * 這個就是我們要代理的真實對象 */ private Object target; /** * 構造方法,給我們要代理的真實對象賦初值 * @param subject */ public LogInterceptor(Object target){ this.target = target; }/** * 該方法負責集中處理動態代理類上的所有方法調用。 * 調用處理器根據這三個參數進行預處理或分派到委托類實例上反射執行 * @param proxy 代理類實例 * @param method 被調用的方法對象 * @param args 調用參數 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ //在代理真實對象前我們可以添加一些自己的操作 System.out.println("trancation start"); //當代理對象調用真實對象的方法時,其會自動的跳轉到代理對象關聯的handler對象的invoke方法來進行調用 Object returnValue = method.invoke(target, args); //在代理真實對象後我們也可以添加一些自己的操作 System.out.println("trancation commit"); return returnValue; } }
4.用Proxy創建代理類的實列subjectProxy
Proxy
提供用於創建動態代理類和實例的靜態方法,它還是由這些方法創建的所有動態代理類的超類。(參考API)
package javaee.net.cn.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * 動態代理演示 * 通過分析代碼可以看出Java 動態代理,具體有如下四步驟: 通過實現 InvocationHandler 接口創建自己的調用處理器; 通過為 Proxy 類指定 ClassLoader 對象和一組 interface 來創建動態代理類; 通過反射機制獲得動態代理類的構造函數,其唯一參數類型是調用處理器接口類型; 通過構造函數創建動態代理類實例,構造時調用處理器對象作為參數被傳入。 */ public class Test{ public static void main(String[] args) { //代理的真實對象 Subject realSubject = new RealSubject(); InvocationHandler handler = new LogInterceptor(realSubject); ClassLoader loader = realSubject.getClass().getClassLoader(); Class<?>[] interfaces = realSubject.getClass().getInterfaces(); /** * 該方法用於為指定類裝載器、一組接口及調用處理器生成動態代理類實例 */ Subject subjectProxy = (Subject) Proxy.newProxyInstance(loader, interfaces, handler); subjectProxy.save(); } }
下面是方法運行的結果
trancation start
insert into ......
trancation commit
像是Spring的事物吧。Spring AOP管理的事物,原理也是動態代理
這是對反射和classLoader的一些補充解釋
JD設計模式之——動態代理