(十七)關於動態代理,你能說出動態代理的幾種方式?
微信搜尋《Java魚仔》,每天一個知識點不錯過
所有內容以及歷史知識點均會更新到github上,歡迎star
(一)每天一個知識點
給我講講多執行緒鎖的升級原理是什麼?
(二)詳解
動態代理是指代理類不是寫在程式碼中的,而是在程式碼執行過程中產生的,Java提供了兩種方式來實現動態代理,分別是基於Jdk的動態代理和基於Cglib的動態代理。
2.1 基於Jdk的動態代理
首先我們來搭建一套實現動態代理的實現,以租房為例,我新建一個租房的介面:
public interface Room {
void rent();
}
然後下一個實際的租房實現類
public class RealRoom implements Room {
private String roomname;
public RealRoom(String roomname) {
this.roomname = roomname;
}
public void rent() {
System.out.println("租了"+roomname);
}
}
基於Jdk的動態代理核心在於InvocationHandler 介面,首先我們新建一個類ProxyHandler來實現這個InvocationHandler 介面,並實現裡面的invoke方法
public class ProxyHandler implements InvocationHandler {
Object object;
public ProxyHandler(Object object) {
this.object = object;
}
//proxy 代理物件
//method 要實現的方法
//args 方法的引數
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理執行之前:"+method.getName());
Object invoke = method.invoke(object, args);
System.out.println("代理執行之後:"+method.getName());
return invoke;
}
}
InvocationHandler 是一個介面,每個代理的例項都有一個與之關聯的 InvocationHandler 實現類,如果代理的方法被呼叫,那麼代理便會通知和轉發給內部的 InvocationHandler 實現類invoke,由它實現處理內容。
接下來寫一個方法來實現動態代理
public static void main(String[] args) {
Room room=new RealRoom("碧桂園");
//obj.getClass().getClassLoader()類載入器
//obj.getClass().getInterfaces() 目標類實現的介面
//InvocationHandler物件
InvocationHandler invocationHandler=new ProxyHandler(room);
Room proxyRoom = (Room) Proxy.newProxyInstance(room.getClass().getClassLoader(), room.getClass().getInterfaces(), invocationHandler);
proxyRoom.rent();
}
這段程式碼的另外一個核心是Proxy.newProxyInstance,該方法需要三個引數,目的是執行期間生成代理類,每個引數的功能已經寫在了註釋中。這段程式碼的意思就是Proxy 動態產生的代理物件會呼叫 InvocationHandler 實現類invoke。
最終我們不需要RealRoom去呼叫rent方法,通過代理類就可以實現這個rent方法。
最後結果如下:
代理執行之前:rent
租了碧桂園
代理執行之後:rent
執行時就會在控制檯上列印出來,這也是Spring AOP的核心
JDK動態代理類實現了InvocationHandler介面,重寫的invoke方法。
JDK動態代理的基礎是反射機制(method.invoke(物件,引數))Proxy.newProxyInstance()
2.2 基於Cglib的動態代理
基於Jdk的動態代理侷限性在於代理的類必須要實現介面,而基於CGlib的動態代理則沒有這個限制:
搭建CGlib環境我們首先要引入一個CGlib的jar包:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
此時我們不再需要介面,直接新建一個CGRoom類:
public class CGRoom {
public void rent(String roomName){
System.out.println("租了"+roomName);
}
}
CGlib實現動態代理的核心在於MethodInterceptor介面:
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代理執行之前:"+method.getName());
Object object=methodProxy.invokeSuper(o,objects);
System.out.println("代理執行之後:"+method.getName());
return object;
}
這個介面只有一個intercept()方法,攔截被代理物件,這個方法有4個引數:
1)表示增強的物件,即實現這個介面類的一個物件;
2)表示要被攔截的方法;
3)表示要被攔截方法的引數;
4)表示要觸發父類的方法物件;
最後生成代理類物件並輸出執行結果
public static void main(String[] args) {
//建立Enhancer物件,類似於JDK動態代理的Proxy類,下一步就是設定幾個引數
Enhancer enhancer=new Enhancer();
//設定目標類的位元組碼檔案
enhancer.setSuperclass(CGRoom.class);
//設定回撥函式
enhancer.setCallback(new MyMethodInterceptor());
//建立代理物件
CGRoom proxy= (CGRoom) enhancer.create();
proxy.rent("碧桂園");
}
執行結果:
代理執行之前:rent
租了碧桂園
代理執行之後:rent
(三)總結
兩種代理方式各有優劣,在使用方面,JDK動態代理只能基於介面進行實現,而CGLIb對代理的目標物件無限制,無需實現介面。
在依賴方面,Java原生支援JDK動態代理,而CGlib的實現還需要引入相關依賴包。
相關文章
- 動態代理的兩種方式以及區別
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- 你必須會的 JDK 動態代理和 CGLIB 動態代理JDKCGLib
- 代理模式詳解:靜態代理、JDK動態代理與Cglib動態代理模式JDKCGLib
- 靜態代理和動態代理
- JAVA 靜態代理 & 動態代理Java
- 代理模式 - 動態代理模式
- Spring AOP --JDK動態代理方式SpringJDK
- 動態代理
- Java中的靜態代理和動態代理Java
- 靜態代理、動態代理與Mybatis的理解MyBatis
- 3.靜態代理&動態代理&CGlibCGLib
- AOP之靜態代理VS動態代理
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- Spring AOP裡的靜態代理和動態代理,你真的瞭解嘛?Spring
- JDK動態代理JDK
- CGLib 動態代理CGLib
- spring動態代理Spring
- java動態代理Java
- Spring 動態代理Spring
- Java代理設計模式(Proxy)的四種具體實現:靜態代理和動態代理Java設計模式
- java動態代理動態在哪裡?Java
- 輕鬆理解 Java 靜態代理/動態代理Java
- JDK動態代理和CGLib代理JDKCGLib
- JDK動態代理和 CGLIB 代理JDKCGLib
- 細說JDK動態代理的實現原理JDK
- 讓我們打一場動態代理的官司–Java動態代理Java
- cglib動態代理和jdk動態代理的區別與應用CGLibJDK
- 基於JDK的動態代理原理分析JDK
- 由《尋秦記》說代理模式(靜態,動態,CGLib)模式CGLib
- Spring動態代理的生成-如何判斷是使用JDK動態代理還是CGlib代理SpringJDKCGLib
- 動態ip代理的三種使用方法
- 深入理解靜態代理與JDK動態代理JDK
- 靜態代理和動態代理(jdk/cglib)詳解JDKCGLib
- Java基礎系列-靜態代理和動態代理Java
- 動態代理架構架構
- java動態代理(1)Java
- Java動態代理(AOP)Java