詳解java動(dòng)態(tài)代理模式
本文針對(duì)java動(dòng)態(tài)代理進(jìn)行知識(shí)點(diǎn)整理,具體內(nèi)容如下
一. JAVA的動(dòng)態(tài)代理(比較官方說(shuō)法)
代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處 理消息、過(guò)濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等?! 〈眍惻c委托類之間通常會(huì)存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對(duì)象與一個(gè)委托類的對(duì)象關(guān)聯(lián),代理類的 對(duì)象本身并不真正實(shí)現(xiàn)服務(wù),而是通過(guò)調(diào)用委托類的對(duì)象的相關(guān)方法,來(lái)提 供特定的服務(wù)。
按照代理的創(chuàng)建時(shí)期,代理類可以分為兩種。
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。
動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。
二. 動(dòng)態(tài)代理實(shí)現(xiàn)
java.lang.reflect.Proxy,
Proxy 提供用于創(chuàng)建動(dòng)態(tài)代理類和實(shí)例的靜態(tài)方法.
newProxyInstance()
返回一個(gè)指定接口的代理類實(shí)例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序。
2.1. Dao接口(提供模擬數(shù)據(jù)訪問(wèn)層接口)
package javaproxy;
/*
* 定義一個(gè)數(shù)據(jù)訪問(wèn)層接口
*/
public interface Dao {
//模擬數(shù)據(jù)保存
public void save();
}
2.2. DaoImpl類實(shí)現(xiàn)類
package javaproxy;
public class DaoImpl implements Dao{
@Override
public void save() {
System.out.println("執(zhí)行一個(gè)保存方法。。。。。。。。。。。。");
}
}
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) {
// 元對(duì)象(被代理對(duì)象)
DaoImpl daoImpl = new DaoImpl();
// 業(yè)務(wù)代理類
DaoHandler daoHandler=new DaoHandler(daoImpl);
Dao dao=(Dao) Proxy.newProxyInstance(daoImpl
.getClass().getClassLoader(), daoImpl.getClass()
.getInterfaces(), daoHandler);
dao.save();
}
}
2. 5. 結(jié)果

3. 模擬Mybatis中的代理實(shí)現(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")
/*
* 這里通過(guò)靜態(tài)方法得到實(shí)現(xiàn)類的對(duì)象
*
* @param:接口
*
* @param:用sqlsession執(zhí)行方法
*
* @return: 返回代理對(duì)像
*/
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:代理對(duì)象
*
* @param:方法通過(guò)方法名字找到對(duì)應(yīng)的方法
*
* @param:通過(guò)方法傳入對(duì)象找到對(duì)應(yīng)的傳遞參數(shù)映射
*
* @return:返回執(zhí)行后的參數(shù)對(duì)象
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 這里通過(guò)方法名字以及參數(shù)通過(guò)解析對(duì)應(yīng)的mapper來(lái)執(zhí)行對(duì)應(yīng)的操作
System.out.println("在這里執(zhí)行實(shí)際方法");
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動(dòng)態(tài)代理的例子,希望對(duì)大家學(xué)習(xí)java程序設(shè)計(jì)有所幫助。
- Java簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)代理模式過(guò)程解析
- Java代理模式實(shí)例詳解【靜態(tài)代理與動(dòng)態(tài)代理】
- Java動(dòng)態(tài)代理模式的深入揭秘
- Java設(shè)計(jì)模式之動(dòng)態(tài)代理模式實(shí)例分析
- JAVA動(dòng)態(tài)代理模式(從現(xiàn)實(shí)生活角度理解代碼原理)
- java 代理模式及動(dòng)態(tài)代理機(jī)制深入分析
- java代理模式與動(dòng)態(tài)代理模式詳解
- 代理模式之Java動(dòng)態(tài)代理實(shí)現(xiàn)方法
- Java代理模式與動(dòng)態(tài)代理之間的關(guān)系以及概念
相關(guān)文章
JavaMail實(shí)現(xiàn)帶附件的郵件發(fā)送
這篇文章主要為大家詳細(xì)介紹了JavaMail實(shí)現(xiàn)帶附件的郵件發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
關(guān)于mybatis遇到Integer類型的參數(shù)時(shí)動(dòng)態(tài)sql需要注意條件
這篇文章主要介紹了關(guān)于mybatis遇到Integer類型的參數(shù)時(shí)動(dòng)態(tài)sql需要注意條件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
MyBatisPlus+Lombok實(shí)現(xiàn)分頁(yè)功能的方法詳解
Lombok是一個(gè)Java類庫(kù),提供了一組注解,簡(jiǎn)化POJO實(shí)體類開(kāi)發(fā)。本文將為大家介紹一下Lombok的使用以及如何利用MyBatisPlus+Lombok實(shí)現(xiàn)分頁(yè)功能,感興趣的可以動(dòng)手嘗試一下2022-07-07
詳解java中的6種單例寫(xiě)法及優(yōu)缺點(diǎn)
在java中,單例有很多種寫(xiě)法,面試時(shí),手寫(xiě)代碼環(huán)節(jié),除了寫(xiě)算法題,有時(shí)候也會(huì)讓手寫(xiě)單例模式,這里記錄一下單例的幾種寫(xiě)法和優(yōu)缺點(diǎn)。需要的朋友可以參考下2018-11-11
java基于websocket實(shí)現(xiàn)im聊天功能
這篇文章主要為大家介紹了java基于websocket實(shí)現(xiàn)im聊天功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
java 替換docx文件中的字符串方法實(shí)現(xiàn)
這篇文章主要介紹了java 替換docx文件中的字符串方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02

