天天看點

Java動态代理學習2——靜态代理和動态代理并對照spring的通知

一、代理模式 

代理模式是常用的java設計模式,特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事後處理消息等。

代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身并不真正實作服務,而是通過調用委托類的對象的相關方法,來提供特定的服務。 

按照代理的建立時期,代理類可以分為兩種:

靜态代理:由程式員建立或特定工具自動生成源代碼再對其編譯。在程式運作前代理類的.class檔案就已經存在了。 

動态代理:在程式運作時運用反射機制動态建立而成。 

二、靜态代理

觀察代碼可以發現每一個代理類隻能為一個接口服務,這樣一來程式開發中必然會産生過多的代理,而且所有的代理操作除了調用的方法不一樣之外其他的操作都一樣,則此時肯定是重複代碼。解決這一問題最好的做法是可以通過一個代理類完成全部的代理功能,那麼此時就必須使用動态代理完成。 

三、動态代理

與靜态代理類對照的是動态代理類,動态代理類的位元組碼在程式運作時由java反射機制動态生成,無需程式員手工編寫它的源代碼。動态代理類不僅簡化了程式設計工作,而且提高了軟體系統的可擴充性,因為java 反射機制可以生成任意類型的動态代理類。java.lang.reflect 包中的proxy類和invocationhandler 接口提供了生成動态代理類的能力。

1 jdk動态代理

jdk動态代理中包含一個類和一個接口

invocationhandler接口

object proxy:指被代理的對象。

method method:要調用的方法

object[] args:方法調用時所需要的參數

可以将invocationhandler接口的子類想象成一個代理的最終操作類,替換掉proxysubject

proxy類

proxy類是專門完成代理的操作類,可以通過此類為一個或多個接口動态地生成實作類,此類提供了如下的操作方法:

classloader loader:類加載器

class<?>[] interfaces:得到全部的接口

invocationhandler h:得到invocationhandler接口的子類執行個體

前置通知

人員增加

後置通知

最終通知

jdk的動态代理依靠接口實作,如果有些類并沒有實作接口,則不能使用jdk代理,這就要使用cglib動态代理了。 

2 cglib動态代理

jdk的動态代理機制隻能代理實作了接口的類,而不能實作接口的類就不能實作jdk的動态代理,cglib是針對類來實作代理的,他的原理是對指定的目标類生成一個子類,并覆寫其中方法實作增強,但因為采用的是繼承是以不能對final修飾的類進行代理。 

增加人員

--------------------