什麼是代理(Proxy)
代理就是被代理對象的代表,代理具有被代理對象的所有能力,不然怎麼代理呢?:) 代理分為靜態和動態代理,下文將會分別介紹。
靜態代理
代理具有被代理對象的能力則意味著他們具有同樣的接口。
那什麼是靜態代理呢?就是這個代理類在程序運行前已經存在了,需要我們自己去實現一個代理類,需要經歷編寫編譯這個過程。
動態代理
動態代理就是在程序運行時動態創建的。代理類將根據需求動態的創建出來,不需要我們自己來實現。
Java如何實現動態代理
Proxy類提供了方法來動態的創建代理類。
<code>public
static
Object newProxyInstance(ClassLoader loader,Class
>[]interfaces
,InvocationHandler
h
) /<code>
為了能夠創建代理類,我們需要告訴Proxy兩樣東西。
- 這個要生成的代理類需要實現哪些接口
- 這些接口中的方法的實現邏輯
接口中方法的實現邏輯是可變的,不同的需求對應不同的邏輯,這部分可變的內容被封裝到了InvocationHandler中。
萬事俱備,生成的代理類將會實現指定的接口,接口的方法實現調用InvocationHandler中的invoke方法。
<code>public
interface
InvocationHandler {public
Object
invoke(Object
proxy, Method method,Object
[] args) throws Throwable; } /<code>
當調用生成的proxy實例上的方法時,生成的proxy class會把被調用的方法信息都封裝起來傳給invoke方法, 這樣InvocationHandler可以做任何邏輯在這裡。通常InvocationHandler將會調用被代理對象的方法來達到代理的目的。
動態代理在mybatis中的應用
如果你在用mybatis這個持久化框架的話,你一定用過Mapper。Mapper只是一個接口,當你從SqlSession中獲得一個Mapper時,Mybatis 會調用java.lang.reflect.Proxy來生成一個實現了這個Mapper的代理類。
<code>public
class
MapperProxy
<T
>implements
InvocationHandler
,Serializable
{ ... }public
class
MapperProxyFactory
<T
> { ...protected
T newInstance(MapperProxy mapperProxy) {return
(T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),new
Class
[] { mapperInterface }, mapperProxy); } ... } /<code>