詳解java動態(tài)代理模式
本文針對java動態(tài)代理進行知識點整理,具體內(nèi)容如下
一. JAVA的動態(tài)代理(比較官方說法)
代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處 理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等?! 〈眍惻c委托類之間通常會存在關(guān)聯(lián)關(guān)系,一個代理類的對象與一個委托類的對象關(guān)聯(lián),代理類的 對象本身并不真正實現(xiàn)服務,而是通過調(diào)用委托類的對象的相關(guān)方法,來提 供特定的服務。
按照代理的創(chuàng)建時期,代理類可以分為兩種。
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經(jīng)存在了。
動態(tài)代理:在程序運行時,運用反射機制動態(tài)創(chuàng)建而成。
二. 動態(tài)代理實現(xiàn)
java.lang.reflect.Proxy,
Proxy 提供用于創(chuàng)建動態(tài)代理類和實例的靜態(tài)方法.
newProxyInstance()
返回一個指定接口的代理類實例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序。
2.1. Dao接口(提供模擬數(shù)據(jù)訪問層接口)
package javaproxy; /* * 定義一個數(shù)據(jù)訪問層接口 */ public interface Dao { //模擬數(shù)據(jù)保存 public void save(); }
2.2. DaoImpl類實現(xiàn)類
package javaproxy; public class DaoImpl implements Dao{ @Override public void save() { System.out.println("執(zhí)行一個保存方法。。。。。。。。。。。。"); } }
2.3. 代理處理類
package javaproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DaoHandler implements InvocationHandler{ private Object obj; public DaoHandler(Object obj) { this.obj=obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do something before method");//這里模擬AOP的前置方法 Object ret = method.invoke(this.obj, args); System.out.println("do something after method");//這里模擬AOP的后置方法 return ret; } }
2.4. client調(diào)用
package javaproxy; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // 元對象(被代理對象) DaoImpl daoImpl = new DaoImpl(); // 業(yè)務代理類 DaoHandler daoHandler=new DaoHandler(daoImpl); Dao dao=(Dao) Proxy.newProxyInstance(daoImpl .getClass().getClassLoader(), daoImpl.getClass() .getInterfaces(), daoHandler); dao.save(); } }
2. 5. 結(jié)果
3. 模擬Mybatis中的代理實現(xiàn)
3.1. MapperProxy類
package javaproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MapperProxy implements InvocationHandler { @SuppressWarnings("unchecked") /* * 這里通過靜態(tài)方法得到實現(xiàn)類的對象 * * @param:接口 * * @param:用sqlsession執(zhí)行方法 * * @return: 返回代理對像 */ public static <T> T newMapperProxy(Class<T> mapperInterface, Object sqlSession) { ClassLoader classLoader = mapperInterface.getClassLoader(); Class<?>[] interfaces = new Class[] { mapperInterface }; MapperProxy proxy = new MapperProxy(); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); } /* * (non-Javadoc) * * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, * java.lang.reflect.Method, java.lang.Object[]) * * @param:代理對象 * * @param:方法通過方法名字找到對應的方法 * * @param:通過方法傳入對象找到對應的傳遞參數(shù)映射 * * @return:返回執(zhí)行后的參數(shù)對象 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 這里通過方法名字以及參數(shù)通過解析對應的mapper來執(zhí)行對應的操作 System.out.println("在這里執(zhí)行實際方法"); return null; } }
3.2. Client
package javaproxy; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { Dao dao=MapperProxy.newMapperProxy(Dao.class, null); dao.save(); } }
3.3. 結(jié)果
以上是使用JDK動態(tài)代理的例子,希望對大家學習java程序設計有所幫助。
相關(guān)文章
關(guān)于mybatis遇到Integer類型的參數(shù)時動態(tài)sql需要注意條件
這篇文章主要介紹了關(guān)于mybatis遇到Integer類型的參數(shù)時動態(tài)sql需要注意條件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03MyBatisPlus+Lombok實現(xiàn)分頁功能的方法詳解
Lombok是一個Java類庫,提供了一組注解,簡化POJO實體類開發(fā)。本文將為大家介紹一下Lombok的使用以及如何利用MyBatisPlus+Lombok實現(xiàn)分頁功能,感興趣的可以動手嘗試一下2022-07-07