一、JDK靜態代理
- 業務接口
- 接口的實現類
- 代理類,實現接口,並擴展實現類的功能
### 二、JDK動態代理性能
- 業務接口
- 實現了業務接口的業務類
- 實現了InvocationHandler接口的handler代理類
三、CGLIB動態代理
不須要定義業務接口代理
- 業務類(不須要實現接口)
- cglib代理類(實現接口MethodInterceptor)
四、原理
一、JDK靜態代理
通常是代理類對象直接包裝被代理對象
二、JDK動態代理對象
- 是接口代理;
- 被代理類須要實現業務接口;
- 業務代理類須要實現InvocationHandler接口;
- JDK動態代理會根據被代理對象生成一個繼承Proxy類,並實現該業務接口的JDK代理類,該類的字節碼會被傳進去的ClassLoader加載,建立JDK代理對象實例;
- JDK代理對象實例建立
- 建立業務代理對象實例;
- 1中的實例賦值給Proxy類;
- 經過2,JDK代理對象實例也就有了業務代理對象實例;
- JDK代理對象實例經過反射,根據被代理類的業務方法建立相應的Method對象(可能有多個);
- JDK代理對象實例調用業務方法時,會先把Method對象做爲參數傳遞給invoke()方法(invoke方法的第二個參數);
調用JDK代理對象實例的invoke()回調方法,在invoke方法裏經過反射來調用代理對象的方法;繼承
三、CGLIB動態代理接口
- 是繼承代理;
- 由於是繼承,全部類和方法都不能用final修飾符;
五、JDK動態代理和CGLIB動態代理
只能代理實現了接口的類;沒有實現接口的類不能實現JDK動態代理 |
針對類來實現代理;對指定目標類產生一個子類,經過方法攔截技術攔截全部父類方法的調用 |
六、三種代理方式的優缺點
JDK靜態代理io
缺點編譯
- 只能爲一個被代理類服務,若是須要代理多個類,會產生過多的代理類;
優勢table
- 在編譯時產生class文件,運行時無需產生,能夠直接使用,效率好;
JDK動態代理class
缺點效率
- 必須實現接口;
- 經過反射動態代理方法,消耗系統性能;
優勢
CGLIB動態代理
缺點
- CGLIB會繼承被代理類;
- CGLIB會重寫被代理方法;
- 代理類和代理方法不能使用final修飾符;
優勢
- 無需實現接口,經過子類字節碼來實現;
- 比反射速度快,沒有性能問題;