用過MyBatis3的人可能會覺得為什麼MyBatis的Mapper介面沒有實作類,但可以直接用?
那是因為MyBatis使用Java動態代理實現的介面。
這裡僅舉個簡單例子來說明原理,不是完全針對MyBatis的,這種想法我們也可以應用在其他地方。
<span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> MethodInterface { String helloWorld(); }
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MethodProxy<T> <span style="color: #0000ff">implements</span><span style="color: #000000"> InvocationHandler { </span><span style="color: #0000ff">private</span> Class<T><span style="color: #000000"> methodInterface; </span><span style="color: #0000ff">public</span> MethodProxy(Class<T><span style="color: #000000"> methodInterface) { </span><span style="color: #0000ff">this</span>.methodInterface =<span style="color: #000000"> methodInterface; } @Override </span><span style="color: #0000ff">public</span> Object invoke(Object proxy, Method method, Object[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Throwable { System.out.println(</span>"========================="<span style="color: #000000">); System.out.println(</span>"方法名:" +<span style="color: #000000"> method.getName()); </span><span style="color: #008000">//</span><span style="color: #008000">针对不同的方法进行不同的操作</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span><span style="color: #000000">; } }</span>
這裡針對invoke
方法簡單說說MyBatis的實作原理,在這個方法中,我們透過Method能夠取得介面和方法名,介面的全名相當於MyBatis XML中的namespace
,方法名稱相當於具體一個方法中的id
。也就是說經過動態代理程式後,可以透過SqlSession
來透過namespace.id
方式來呼叫對應的方法。使用介面比較方便,但是是一種間接的方式。
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> MethodProxyFactory { </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <T> T newInstance(Class<T><span style="color: #000000"> methodInterface) { </span><span style="color: #0000ff">final</span> MethodProxy<T> methodProxy = <span style="color: #0000ff">new</span> MethodProxy<T><span style="color: #000000">(methodInterface); </span><span style="color: #0000ff">return</span><span style="color: #000000"> (T) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), </span><span style="color: #0000ff">new</span><span style="color: #000000"> Class[]{methodInterface}, methodProxy); } }</span>
透過此工廠類別可以產生任意介面的動態代理類別。
MethodInterface method = MethodProxyFactory.newInstance(MethodInterface.<span style="color: #0000ff">class</span><span style="color: #000000">); method.helloWorld();</span>
一般談到動態代理我們通常的用法都是處理交易、日誌或記錄方法執行效率等方面的應用。都是實現類別方法的前置或後置的特殊處理。
透過本文,其實可以看到另一種應用方向,那就是不需要實作類,直接透過動態代理執行介面方法,MyBatis使用這種方式方便了我們呼叫方法,利用這個想法我們也許可以在別的方面做出一些更好的設計。
原文:
以上是【轉】MyBatis介面的簡單實作原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!