【設計模式】動態代理實現事物管理

一、基礎概念

 

代理模式:爲對象提供一種代理,以控制對這個對象的訪問。

圖中,一個接口Subject,真正的實現類RealSuject,代理類Proxy也繼承這個接口,並引用了真正的實體類,可以通過實現接口下面的方法,來對方法進行修改,客戶端直接調用代理類來實現想在方法中添加的功能。

二、代理模式分爲動態代理和靜態代理:

動態代理:在程序運行的時候,類使用的時候進行調用,不用的時候不創建

靜態代理:在類加載使用之前,在程序運行的時候就已經創建好

三、應用場景:

在不借助spring框架下,需要對數據進行增刪改操作的方法,總是需要自己調用事物,手動開啓關閉回滾事物。這些事情可以通過動態代理來實現。

package com.bjpowernode.drp.util;

/**
* 採用動態代理封裝事務
* @author Administrator
*
*/
public class TransactionHandler implements InvocationHandler {
   private Object targetObject;
   public Object newProxyInstance(Object targetObject) {
      this.targetObject = targetObject;
      return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                        targetObject.getClass().getInterfaces(), this);
   }

   public Object invoke(Object proxy, Method method, Object[] args)
         throws Throwable {
      Connection conn = null;
      Object ret = null;
      try {
         //從ThreadLocal中取得Connection
         conn = ConnectionManager.getConnection();
         if (method.getName().startsWith("add") ||
            method.getName().startsWith("del") ||
            method.getName().startsWith("modify")) {
            //手動控制事務提交
            ConnectionManager.beginTransaction(conn);
         }  
         //調用目標對象的業務邏輯方法
         ret = method.invoke(targetObject, args);
         if (!conn.getAutoCommit()) {
            //提交事務
            ConnectionManager.commitTransaction(conn);
         }
      }catch(ApplicationException e) {
         //回滾事務
         ConnectionManager.rollbackTransaction(conn);
         throw e;
      }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;
   }
}
動態代理方法:
Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                        targetObject.getClass().getInterfaces(), this);
java.lang.reflect.Proxy:該類用於動態生成代理類,只需傳入目標接口、目標接口的類加載器以及InvocationHandler便可爲目標接口生成代理類及代理對象。
傳入目標對象的加載器:targetObject.getClass().getClassLoader()
該目標對象的接口類:targetObject.getClass().getInterfaces()
調用當前對象:this(目的是調用invoke方法)

小結:

我們不用任何框架的前提下,在前端的請求已經發送過來後需要調用業務邏輯層,並通過抽象工廠+反射來實現需要的業務邏輯層類的實例化的時候,可以插入這個動態代理的類,來對當前實例化後的對象進行動態代理。

比如例子中的,鏈接數據庫,對事物的手動控制。動態代理是spring框架中AOP基礎實現用到的模式。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章