摘要:靜態方法生成動態代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區別就是其字節碼是由在運行時動態生成的而非預存在于任何一個文件中。
代理:設計模式
代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委托類預處理消息,過濾消息并轉發消息,以及進行消息被委托類執行后的后續處理。
java.lang.reflect.Proxy:Proxy 的靜態方法
// 方法 1: 該方法用于獲取指定代理對象所關聯的調用處理器 static InvocationHandler getInvocationHandler(Object proxy) // 方法 2:該方法用于獲取關聯于指定類裝載器和一組接口的動態代理類的類對象 static Class getProxyClass(ClassLoader loader, Class[] interfaces) // 方法 3:該方法用于判斷指定類對象是否是一個動態代理類 static boolean isProxyClass(Class cl) // 方法 4:該方法用于為指定類裝載器、一組接口及調用處理器生成動態代理類實例 static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
ava.lang.reflect.InvocationHandler:InvocationHandler 的核心方法
// 該方法負責集中處理動態代理類上的所有方法調用。第一個參數既是代理類實例,第二個參數是被調用的方法對象 // 第三個方法是調用參數。調用處理器根據這三個參數進行預處理或分派到委托類實例上發射執行 Object invoke(Object proxy, Method method, Object[] args)
java.lang.ClassLoader:這是類裝載器類,負責將類的字節碼裝載到 Java 虛擬機(JVM)中并為其定義類對象,然后該類才能被使用。Proxy 靜態方法生成動態代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區別就是其字節碼是由 JVM 在運行時動態生成的而非預存在于任何一個 .class 文件中。
代碼實例Client.java
public class Client { public static void main(String[] args) { LogHandler logHandler = new LogHandler(); UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl()); userManager.addUser("0001", "User1"); } }
myHandler.java
public class MyHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObject) { this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { StringBuilder sb = new StringBuilder(); for (Object o: args){ sb.append(o.toString()); sb.append(","); } sb.setLength(sb.length()-1); System.out.println("invoke: start "+method.getName()+"("+ sb.toString()+ ")"); Object ret = null; try { ret = method.invoke(targetObject, args); System.out.println("invoke: success"); }catch(Exception e) { System.out.println("invoke: error"); e.printStackTrace(); throw e; } return ret; } }
UserManager.java
public interface UserManager { public void addUser(String userId, String userName); }
UserManagerImpl.java
public class UserManagerImpl implements UserManager { public void addUser(String userId, String userName) { System.out.println("addUser: function call"); } }參考資料
Java 動態代理機制
利用動態代理的 Java 驗證
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65716.html
摘要:動態代理有多種不同的用途,例如,數據庫連接和事務管理用于單元測試的動態模擬對象其他類似的方法攔截。調用序列和下面的流程類似單元測試動態對象模擬利用動態代理實現單元測試的動態存根代理和代理。框架把包裝成動態代理。 使用反射可以在運行時動態實現接口。這可以使用類java.lang.reflect.Proxy。這個類的名稱是我將這些動態接口實現稱之為動態代理的原因。動態代理有多種不同的用途,...
摘要:反射使用類對象提供的基本元數據,能從類對象中找出方法或字段的名稱,然后獲取表示方法或字段的對象。常見的反射手段有反射和反射。以之前的反射為例其中指定了方法的返回類型,其實不止如此。 Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類 在運行時構造任意一個類的對象 在運行時判斷任意一個類所具有的成員變量和方法 在運行時調用任意一個對象的方法 生成動態代理 很多框架...
摘要:相比硬編碼,反射要復雜的多,但其給我們帶來了更大的靈活性。實際上構造函數也是類的靜態方法,因此使用關鍵字創建類的新對象也會被當做對類的靜態引用,從而觸發類加載器對類的加載。基礎基礎主要是為反射提供通用特性的接口或基類。 1. Java類型系統 獲取Java類型系統,主要有兩個方式:一種是傳統的RTTI(Run-Time Type Identification),它假定我們在編譯時已經知...
摘要:接口與類型信息關鍵字的一種重要目標就是允許程序員隔離構件,進而降低耦合性。如果你編寫接口,那么就可以實現這一目標,但是通過類型信息,這種耦合性還是會傳播出去接口并非是對解耦的一種無懈可擊的保障。 點擊進入我的博客 運行時類型信息使得你可以在運行時發現和使用類型信息,主要有兩種方式: 傳統的RTTI,它假定我們在編譯時已經知道了所有的類型; 反射機制,它允許我們在運行時發現和使用類的...
閱讀 1660·2021-11-16 11:41
閱讀 2458·2021-11-08 13:14
閱讀 3106·2019-08-29 17:16
閱讀 3079·2019-08-29 16:30
閱讀 1843·2019-08-29 13:51
閱讀 356·2019-08-23 18:38
閱讀 3223·2019-08-23 17:14
閱讀 630·2019-08-23 15:09