摘要:靜態(tài)方法生成動態(tài)代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區(qū)別就是其字節(jié)碼是由在運行時動態(tài)生成的而非預存在于任何一個文件中。
代理:設計模式
代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委托類預處理消息,過濾消息并轉(zhuǎn)發(fā)消息,以及進行消息被委托類執(zhí)行后的后續(xù)處理。
java.lang.reflect.Proxy:Proxy 的靜態(tài)方法
// 方法 1: 該方法用于獲取指定代理對象所關(guān)聯(lián)的調(diào)用處理器 static InvocationHandler getInvocationHandler(Object proxy) // 方法 2:該方法用于獲取關(guān)聯(lián)于指定類裝載器和一組接口的動態(tài)代理類的類對象 static Class getProxyClass(ClassLoader loader, Class[] interfaces) // 方法 3:該方法用于判斷指定類對象是否是一個動態(tài)代理類 static boolean isProxyClass(Class cl) // 方法 4:該方法用于為指定類裝載器、一組接口及調(diào)用處理器生成動態(tài)代理類實例 static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
ava.lang.reflect.InvocationHandler:InvocationHandler 的核心方法
// 該方法負責集中處理動態(tài)代理類上的所有方法調(diào)用。第一個參數(shù)既是代理類實例,第二個參數(shù)是被調(diào)用的方法對象 // 第三個方法是調(diào)用參數(shù)。調(diào)用處理器根據(jù)這三個參數(shù)進行預處理或分派到委托類實例上發(fā)射執(zhí)行 Object invoke(Object proxy, Method method, Object[] args)
java.lang.ClassLoader:這是類裝載器類,負責將類的字節(jié)碼裝載到 Java 虛擬機(JVM)中并為其定義類對象,然后該類才能被使用。Proxy 靜態(tài)方法生成動態(tài)代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區(qū)別就是其字節(jié)碼是由 JVM 在運行時動態(tài)生成的而非預存在于任何一個 .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 動態(tài)代理機制
利用動態(tài)代理的 Java 驗證
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65716.html
摘要:動態(tài)代理有多種不同的用途,例如,數(shù)據(jù)庫連接和事務管理用于單元測試的動態(tài)模擬對象其他類似的方法攔截。調(diào)用序列和下面的流程類似單元測試動態(tài)對象模擬利用動態(tài)代理實現(xiàn)單元測試的動態(tài)存根代理和代理??蚣馨寻b成動態(tài)代理。 使用反射可以在運行時動態(tài)實現(xiàn)接口。這可以使用類java.lang.reflect.Proxy。這個類的名稱是我將這些動態(tài)接口實現(xiàn)稱之為動態(tài)代理的原因。動態(tài)代理有多種不同的用途,...
摘要:反射使用類對象提供的基本元數(shù)據(jù),能從類對象中找出方法或字段的名稱,然后獲取表示方法或字段的對象。常見的反射手段有反射和反射。以之前的反射為例其中指定了方法的返回類型,其實不止如此。 Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類 在運行時構(gòu)造任意一個類的對象 在運行時判斷任意一個類所具有的成員變量和方法 在運行時調(diào)用任意一個對象的方法 生成動態(tài)代理 很多框架...
摘要:相比硬編碼,反射要復雜的多,但其給我們帶來了更大的靈活性。實際上構(gòu)造函數(shù)也是類的靜態(tài)方法,因此使用關(guān)鍵字創(chuàng)建類的新對象也會被當做對類的靜態(tài)引用,從而觸發(fā)類加載器對類的加載?;A(chǔ)基礎(chǔ)主要是為反射提供通用特性的接口或基類。 1. Java類型系統(tǒng) 獲取Java類型系統(tǒng),主要有兩個方式:一種是傳統(tǒng)的RTTI(Run-Time Type Identification),它假定我們在編譯時已經(jīng)知...
摘要:接口與類型信息關(guān)鍵字的一種重要目標就是允許程序員隔離構(gòu)件,進而降低耦合性。如果你編寫接口,那么就可以實現(xiàn)這一目標,但是通過類型信息,這種耦合性還是會傳播出去接口并非是對解耦的一種無懈可擊的保障。 點擊進入我的博客 運行時類型信息使得你可以在運行時發(fā)現(xiàn)和使用類型信息,主要有兩種方式: 傳統(tǒng)的RTTI,它假定我們在編譯時已經(jīng)知道了所有的類型; 反射機制,它允許我們在運行時發(fā)現(xiàn)和使用類的...
閱讀 1682·2021-11-16 11:41
閱讀 2471·2021-11-08 13:14
閱讀 3119·2019-08-29 17:16
閱讀 3089·2019-08-29 16:30
閱讀 1856·2019-08-29 13:51
閱讀 367·2019-08-23 18:38
閱讀 3238·2019-08-23 17:14
閱讀 641·2019-08-23 15:09