【Java技術點滴】——代理模式及其對事務封裝

來源:互聯網
上載者:User

標籤:

背景

    項目中我們會遇到這樣的情況:在幾個方法中加入相同的代碼,這些代碼是與業務無關的,並且以後有可能由於考慮不周或需求變動再或者是其他原因,我們需要對他們進行逐一進行改動。舉個具體的例子,比如程式中的日誌控制、事務控制等,這些功能是與業務無關的,但卻需要將它們與我們的邏輯混在一起,達到一些特殊的需求。

    這樣的情況往往代碼都是相同的,可以抽離出來,為了複用,我們可以將這些相同的代碼單獨封裝成的方法,以供其他需要的地方調用,這樣對於以後的修改就做到了只修改一處的效果,達到了程式的複用,但另外一個問題便是,將來某一天我們可能不需要這樣的功能了,我們就需要將調用這些功能的代碼逐一進行刪除,而且當方法的參數或返回值變動也許要進行每一處調用的修改。

    基於以上的問題,我們可以採用代理模式進行解決。


基本介紹

代理模式(Proxy):為其他對象提供一種代理以控制對這個對象的訪問。

直白些說,我們與需要調用的目標對象之間加上一層(代理類),我們便不直接調用以前的目標對象,而是通過代理類間接調用,這樣,我們就可以在代理裡做那些抽離出的功能了。


代理模式類圖示意

以前的直接調用方式

                    

使用代理模式抽取公用調用部分


分類

靜態:

    靜態代理中的代理類是看得見摸得著的,編譯時間就已經確定了要執行的方法。靜態代理存在著代理類過多的問題。為了更加靈活度的實現,我們可以使用動態代理。


動態:代理類運行時確定

   

    使用:

    1.目標類必須實現某介面

    2.建立代理對象的控制類

    實現InvocationHandler,封裝根據目標對象組建代理程式類的方法,調用方首先調用Proxy的newProxyInstance方法(此部分可以應用原廠模式進行封裝,以後可以進行去除或改變代理類),產生並轉換為代理類,調用此類的目標方法,則可回調到InvocationHandler實作類別的invoke方法


樣本-動態代理封裝事務

public class TransactionHandler implements InvocationHandler {private Object targetObject;public Object newProxyInstance(Object targetObject){this.targetObject = targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),<span style="font-family:KaiTi_GB2312;">      </span>targetObject.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{Connection conn = null;Object ret = null;try{conn = ConnectionManager.getConnection();//開啟事務的配置可採用設定檔,那樣可更加靈活if(method.getName().startsWith("save") ||    method.getName().startsWith("remove") ||   method.getName().startsWith("modify")){   //手動控制事務提交       ConnectionManager.beginTransaction(conn);}//調用目標對象的商務邏輯方法ret = method.invoke(targetObject, args);//判斷,當AutoCommit設定為false的前提下控制提交if(!conn.getAutoCommit()){//提交事務ConnectionManager.commit(conn);}}catch(Exception e){e.printStackTrace();//動態代理對我們自訂的異常進行了封裝if(e instanceof InvocationTargetException){InvocationTargetException ete = (InvocationTargetException)e;throw ete.getTargetException();}//復原事務ConnectionManager.rollbackTransaction(conn);throw new ApplicationException("操作失敗!");}finally{ConnectionManager.closeConnection();}return ret;}}

註:此樣本中的類ConnectionManage具體實現參見【Java技術點滴】——ThreadLocal封裝JDBC事務操作

            經過此類的封裝,我們便可以實現在Service層中需要進行事務操作的地方便不用每次都寫事務相關的代碼了,只要為Service層類組建代理程式,回調此類的的Invoke方法就可以實現事務的控制,這樣就達到了很好的複用和更高的可維護性。


總結

    正因為代理模式為我們帶來了類似於Filter的攔截機制,使我們可以在調用目標方法前做一些事,在調用目標方法後做一些事,這樣就可以達到以前我們一般的編程理論所不能達到的效果,再加上一些靈活配置的附加應用,代理模式的應用可以說是相當廣泛,也為今後的程式設計提供了更多了思路與思想。

【Java技術點滴】——代理模式及其對事務封裝

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.