您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
前言:動(dòng)態(tài)代理是一種常用的設(shè)計(jì)模式,廣泛應(yīng)用于框架中,Spring框架的AOP特性就是應(yīng)用動(dòng)態(tài)代理實(shí)現(xiàn)的,想要理解AOP的實(shí)現(xiàn)原理我們就必須先理解動(dòng)態(tài)代理。
代理模式是GOF23設(shè)計(jì)模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者執(zhí)行功能時(shí)會(huì)附加一些額外的操作
如:手機(jī)工廠和代理商都具有賣東西的功能,手機(jī)代理商除了幫工廠賣手機(jī)外,還能在賣手機(jī)前打廣告推銷,賣手機(jī)后還可以進(jìn)行售后服務(wù)。
代理模式的優(yōu)點(diǎn):
1)符合開(kāi)閉原則,不用修改被代理者任何的代碼,就能擴(kuò)展新的功能
2)項(xiàng)目的擴(kuò)展和維護(hù)比較方便
代理模式分為:靜態(tài)代理和動(dòng)態(tài)代理
什么是靜態(tài)代理
1)代理者和被代理者都實(shí)現(xiàn)了相同的接口(或繼承相同的父類)
2)代理者包含了一個(gè)被代理者的對(duì)象
3)調(diào)用功能時(shí),代理者會(huì)調(diào)用被代理者的功能,同時(shí)附加新的操作
/**
* 賣手機(jī)
*/
public interface SellMobilePhone {
void sellMobilePhone();
}
/**
* 小米手機(jī)工廠
*/
public class MiPhoneFactory implements SellMobilePhone{
public void sellMobilePhone() {
System.out.println("生產(chǎn)了小米9手機(jī),賣出去?。?quot;);
}
}
/**
* 小米代理商
*/
public class MiPhoneAgent implements SellMobilePhone {
//被代理者,工廠對(duì)象
private SellMobilePhone factory;
//通過(guò)構(gòu)造方法傳入被代理者
public MiPhoneAgent(SellMobilePhone factory){
this.factory = factory;
}
public void sellMobilePhone() {
System.out.println("打廣告,做活動(dòng)~~~~~~~~~~~~~~~~~");
//調(diào)用被代理者的方法
factory.sellMobilePhone();
System.out.println("做售后,做推銷~~~~~~~~~~~~~~~~~");
}
}
public class TestStaticProxy {
@Test
public void testProxy(){
//創(chuàng)建被代理者
SellMobilePhone factory = new MiPhoneFactory();
factory.sellMobilePhone();
System.out.println("---------------------------------------");
//創(chuàng)建代理者
SellMobilePhone agent = new MiPhoneAgent(factory);
//調(diào)用賣手機(jī)
agent.sellMobilePhone();
}
}
靜態(tài)代理的問(wèn)題:
靜態(tài)代理只能適合一種業(yè)務(wù),如果有新的業(yè)務(wù),就必須創(chuàng)建新的接口和新的代理,如添加賣電腦的接口和電腦工廠,就要?jiǎng)?chuàng)建新的電腦代理類。
動(dòng)態(tài)代理的特點(diǎn):
1) 在不修改原有類的基礎(chǔ)上,為原來(lái)類添加新的功能
2) 不需要依賴某個(gè)具體業(yè)務(wù)
動(dòng)態(tài)代理分為:JDK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理
區(qū)別是:
JDK動(dòng)態(tài)代理的被代理者必須實(shí)現(xiàn)任意接口
CGLib動(dòng)態(tài)代理不用實(shí)現(xiàn)接口,是通過(guò)繼承實(shí)現(xiàn)的
實(shí)現(xiàn)步驟:
1)代理類需要實(shí)現(xiàn)InvocationHandler接口
2)實(shí)現(xiàn)invoke方法
3)通過(guò)Proxy類的newProxyInstance方法來(lái)創(chuàng)建代理對(duì)象
/**
* 動(dòng)態(tài)代理
*/
public class SalesAgent implements InvocationHandler{
//被代理者對(duì)象
private Object object;
/**
* 創(chuàng)建代理對(duì)象
* @param object 被代理者
* @return 代理者
*/
public Object createProxy(Object object){
this.object = object;
//Proxy.newProxyInstance創(chuàng)建動(dòng)態(tài)代理的對(duì)象,傳入被代理對(duì)象的類加載器,接口,InvocationHandler對(duì)象
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
/**
* 調(diào)用被代理者方法,同時(shí)添加新功能
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("銷售之前,打廣告~~~~~~");
//調(diào)用被代理者的方法
Object result = method.invoke(object,args);
System.out.println("銷售之后,做售后~~~~~~");
return result;
}
}
public class TestInvocationHandler {
@Test
public void testInvocation(){
//創(chuàng)建動(dòng)態(tài)代理對(duì)象
SalesAgent agent = new SalesAgent();
//被代理對(duì)象
SellMobilePhone sellMobilePhone = new MiPhoneFactory();
//創(chuàng)建代理對(duì)象
SellMobilePhone phoneProxy = (SellMobilePhone) agent.createProxy(sellMobilePhone);
phoneProxy.sellMobilePhone();
}
}
特點(diǎn):通過(guò)繼承實(shí)現(xiàn),被代理者必須能被繼承,通過(guò)被代理類創(chuàng)建子類,子類就是父類的代理。
/**
* CGLib動(dòng)態(tài)代理
*
*/
public class CGLibProxy implements MethodInterceptor {
/**
* 返回代理對(duì)象
* @param object 被代理對(duì)象
* @return 代理對(duì)象
*/
public Object createProxy(Object object){
//創(chuàng)建加強(qiáng)器
Enhancer eh = new Enhancer();
//設(shè)置被代理對(duì)象的類為父類
eh.setSuperclass(object.getClass());
//設(shè)置代理對(duì)象的回調(diào)
eh.setCallback(this);
return eh.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("售前~~~~~~CGLIB");
//調(diào)用父類對(duì)象的方法
Object res = proxy.invokeSuper(obj, args);
System.out.println("售后~~~~~~CGLIB");
return res;
}
}
“JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。