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