在java 的動態代理機制中,有兩個重要的類或者接口,一個是InvocationHandler(interface),
另一個則是Proxy(Class).
這一個類和接口是實現我們動態代理所必須用到的。
InvocationHandler:
每一個動態代理類都必須要實現InvocationHandler 這個接口,并且每個代理類的實例都關聯到了
一個handler, 當我們通過代理對象調用一個方法的時候,這個方法的調用
就會被轉發為由InvocationHandler這個接口的invoke方法來進行調用。
Object?invoke(Object?proxy,?Method?method,?Object[]?args)throwsThrowable
proxy:指代我們所代理的那個真實對象
method:指代的是我們所要調用真實對象的某個方法的Method對象
args:指代的是調用真實對象某個方法時接受的參數
Proxy:
Proxy這個類的作用就是用來動態創建一個代理對象的類,它提供了許多的方法,但是我們用的最多的就是newProxyInstance這個方法:
publicstaticObjectnewProxyInstance(ClassLoader?loader,?Class[]?interfaces,? InvocationHandler?h)throwsIllegalArgumentException
loader:一個ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進行加載
interfaces:一個Interface對象的數組,表示的是我將要給我需要代理的對象提供一組什么接口,如果我提供了一組接口給它,那么這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了
h:一個InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候,會關聯到哪一個InvocationHandler對象上
動態代理的主要作用:
主要用來做方法的增強,讓你可以在不修改源碼的情況下,增強一些方法,在方法執行前后做任何你想做的事情(甚至根本不去執行這個方法),因為在InvocationHandler的invoke方法中,你可以直接獲取正在調用方法對應的Method對象,具體應用的話,比如可以添加調用日志,做事務控制等。
Spring 的app切面編程, struct 的攔截器都用到了動態代理的思想