最近在研究RPC框架,避免不了的就是在RPC呼叫中使用最多的則是動態代理的機制了,基於此,我們先來研究一下JDK動態代理
我們先來嘗試著編寫一下JDK動態代理的程式碼
1. 由於JDK動態代理是基於介面的,所以不免需要先編寫一個介面,並宣告一個getHello方法
package cn.lonecloud.study.service; import cn.lonecloud.study.dto.HelloDto; /** * @author lonecloud * @version v1.0 * @Package cn.lonecloud.study * @Description: TODO * @date 2018/6/8下午4:36 */ public interface HelloService { HelloDto getHello(String name); }
2. 有了介面,肯定是需要實現類,並將getHello方法給予實現
package cn.lonecloud.study; import cn.lonecloud.study.dto.HelloDto; import cn.lonecloud.study.service.HelloService; /** * @author lonecloud * @version v1.0 * @Package cn.lonecloud.study * @Description: TODO * @date 2018/6/8下午11:35 */ public class HelloImpl implements HelloService { @Override public HelloDto getHello(String name) { return new HelloDto(); } }
這兩個硬性條件有了,則我們來編寫動態代理類了
1. 首先我們先來了解兩個API:
1. public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h):該類用於建立動態代理類的例項,
1. loader:類的類載入器:一般使用者類為AppClassLoader,可通過類名.class.getClassLoader()獲得
2. interfaces:介面陣列,前面我們說過,jdk動態代理是基於介面來實現的,所以這個引數就是用來傳遞介面陣列啦
3. h:用於具體實現Handler,也就是這裡執行相關的主要業務邏輯的地方了
2. InvocationHandler:該介面用於實現動態代理類的相關業務邏輯
1. 通常需要使用動態代理的話必須實現該介面,並重寫其裡面的invoke方法。
2. invoke(Object proxy, Method method, Object[] args)throws Throwable;
1. proxy:代理類物件
2. method:執行的方法
3. args:相關的引數
編寫相關的代理類
package cn.lonecloud.study; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author lonecloud * @version v1.0 * @Package cn.lonecloud.study * @Description: TODO * @date 2018/6/8下午11:23 */ public class ProxyDemo { //定義實現類物件 Object target; //建構函式 public ProxyDemo(Object target) { this.target = target; } //獲取實現類方法 @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> clazz){ //獲取代理例項 return(T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class[]{clazz}, (proxy, method, args) -> { System.out.println(method.getName()); //執行代理物件 return method.invoke(target,args); }); } }
clazz.getClassLoader()獲取的是類載入器,第二個引數建立了一個Class[]陣列物件,由於傳遞過來的clazz為介面,所以可以這樣寫
執行:
HelloService proxy1 = new ProxyDemo(new HelloImpl()).getProxy(HelloService.class); HelloDto demo = proxy1.getHello("demo");
該JDK動態代理的實現基本上就完成了,下一篇文章我們來看一下,jdk動態代理生產的位元組碼檔案究竟是什麼個樣子