這篇部落格對應上篇部落格《靜態代理模式》,我們來說一下動態代理,靜態代理之所以擴充和維護比較困難,是因為代碼寫的太死,沒有可替換的餘地;針對代碼寫得死能想到什麼解決辦法?對,就是反射。
使用反射可以很到的解決決定載入哪個代理類的問題,避免了每個代理類都要重複寫的問題,話不多說,來看代碼。
動態代理
介面UserManager
/*** * 使用者控制介面 * @author Administrator * */public interface UserManager {public void addUser(String userId,String userName);public void modifyUser(String userId,String userName);public void delUser(String userId);public String findUser(String userId);} 實作類別UserManagerImpl
/**** * 使用者管理真正的實作類別 * @author Administrator * */public class UserManagerImpl implements UserManager { /***** * 添加使用者 */public void addUser(String userId, String userName) {System.out.println("正在添加使用者,使用者為:"+userId+userName+"……");} /***** * 刪除使用者 */public void delUser(String userId) {System.out.println("delUser,userId="+userId);} /*** * 尋找使用者 */public String findUser(String userId) {System.out.println("findUser,userId="+userId);return userId;}public void modifyUser(String userId, String userName) {System.out.println("modifyUser,userId="+userId);}} 代理類LogHandler
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class LogHandler implements InvocationHandler {private Object targetObject;public Object newProxyInstance(Object targetObject) {this.targetObject = targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object ret = null;try {System.out.println("進行中操作前的準備工作……");//調用目標方法ret = method.invoke(targetObject, args);System.out.println("操作成功,進行中確認處理……");} catch (Exception e) {e.printStackTrace();System.out.println("error-->>" + method.getName());throw e;}return ret;}}
用戶端Client
public class Client {/** * @param args */public static void main(String[] args) {LogHandler logHandler = new LogHandler();UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());userManager.findUser("0001");}}
運行結果
時序圖
總結 動態代理模式通過使用反射,可以在運行期決定載入哪個類,避免了一個類對應一個代理的問題;同時,通過統一的invoke方法,統一了代理類對原函數的處理過程,使用動態代理很大程度上減少了重複的代碼,降低了維護的複雜性和成本。
更多DRP系列部落格,其訪問《DRP項目總結》。