Java語言中反射動態代理介面的解釋與示範
Java語言中反射動態代理介面的解釋與示範
Java在JDK1.3的時候引入了動態代理機制、可以運用在架構編程與平台編程時候捕獲事件、審核心數據、日誌等功能實現,首先看一下設計模式的UML圖解:
當你調用一個介面API時候,實際實作類別繼承該介面,調用時候經過proxy實現。
在Java中動態代理實現的兩個關鍵介面類與class類分別如下:
java.lang.reflect.Proxy
java.lang.reflect.InvocationHandler
我們下面就通過InvocationHandler介面來實現動態代理過程,通過Proxy介面建立
一個代理類,然後測試完整的程式。要實現示範Demo需要如下幾步:
一:首先定義我們自己的POJO對象介面類IExample與IUser
package com.example.pojo;public interface IExample {public void setName(String name);public String getName();public void setDesc(String description);public String getDesc();}
package com.example.pojo;public interface IUser {public void setUserID(String userID);public String getUserID();public void setUserName(String userName);public String getUserName();}二:實現我們自己InvocationHandler介面,其中map我用來儲存POJO對象的資料,這樣做的好處是POJO介面無需再建立實作類別,只有定義介面就可以通過代理直接使用該類,這在實際項目開發中非常有用。
package com.example.reflection;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.Map;public class MyProxyView implements InvocationHandler {private Map map = null;public static Object newInstance(Class[] interfaces) {return Proxy.newProxyInstance(MyProxyView.class.getClassLoader(),interfaces, new MyProxyView());}private MyProxyView() {this.map = new HashMap();}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result = null;String methodName = method.getName();if (methodName.startsWith("get")) {String name = methodName.substring(methodName.indexOf("get") + 3);return map.get(name);} else if (methodName.startsWith("set")) {String name = methodName.substring(methodName.indexOf("set") + 3);map.put(name, args[0]);return null;} else if (methodName.startsWith("is")) {String name = methodName.substring(methodName.indexOf("is") + 2);return (map.get(name));}return result;}}
三:通過Proxy方法初始化代理得到POJO對象,運行與測試:
package com.example.reflection;import com.example.pojo.IExample;import com.example.pojo.IUser;public class TextProxy {public static void main(String[] args){IExample example = (IExample)MyProxyView.newInstance(new Class[]{IExample.class});IUser user = (IUser)MyProxyView.newInstance(new Class[]{IUser.class});// aduit bean 1example.setName("my example");example.setDesc("my proxy example");// aduit bean 2user.setUserID("jia20003");user.setUserName("gloomyfish");System.out.println("exmaple name : " + example.getName());System.out.println("exmaple desc : " + example.getDesc());System.out.println();System.out.println("user ID : " + user.getUserID());System.out.println("user name : " + user.getUserName());}}
四:運行結果如下:
exmaple name : my exampleexmaple desc : my proxy exampleuser ID : jia20003user name : gloomyfish
Java動態代理方式對架構編程非常重要無論是在Web端還是案頭端
而真正把這種技術發揚光大的則是spring架構。