1. 程式人生 > >Spring事務管理機制的實現原理-動態代理

Spring事務管理機制的實現原理-動態代理

之前在做專案中遇到spring無法進行事務代理問題,最後發現是因為沒有寫介面,原因當時明白了,看到這篇文章寫的清楚些,轉過來 

我們先來分析一下Spring事務管理機制的實現原理。由於Spring內建AOP預設使用動態代理模式實現,我們就先來分析一下動態代理模式的實現方 法。動態代理模式的核心就在於程式碼中不出現與具體應用層相關聯的介面或者類引用,如上所說,這個代理類適用於任何介面的實現。下面我們來看一個例子。 public class TxHandler implements InvocationHandler {

private Object originalObject;
public Object bind(Object obj) {
 this.originalObject = obj;
 return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
 Object result = null;
 if (!method.getName().startsWith("save")) {
  UserTransaction tx = null;
  try {
   tx = (UserTransaction) (new InitialContext().lookup("java/tx"));
   result = method.invoke(originalObject, args);
   tx.commit();
  } catch (Exception ex) {
   if (null != tx) {
    try {
     tx.rollback();
    } catch (Exception e) {
   }
  }
 }
} else {
 result = method.invoke(originalObject, args);
}
return result;
}
}
  下面我們來分析一下上述程式碼的關鍵所在。

  首先來看一下這段程式碼:

return Proxy.newProxyInstance(
 obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
   java.lang.reflect.Proxy.newProxyInstance方法根據傳入的介面型別 (obj.getClass.getInterfaces())動態構造一個代理類例項返回,這也說明了為什麼動態代理實現要求其所代理的物件一定要實現 一個介面。這個代理類例項在記憶體中是動態構造的,它實現了傳入的介面列表中所包含的所有介面。

  再來分析以下程式碼:

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
 ……
 result = method.invoke(originalObject, args);
 ……
 return result;
}
   InvocationHandler.invoke方法將在被代理類的方法被呼叫之前觸發。通過這個方法,我們可以在被代理類方法呼叫的前後進行一些處 理,如程式碼中所示,InvocationHandler.invoke方法的引數中傳遞了當前被呼叫的方法(Method),以及被呼叫方法的引數。同 時,可以通過method.invoke方法呼叫被代理類的原始方法實現。這樣就可以在被代理類的方法呼叫前後寫入任何想要進行的操作。

   Spring的事務管理機制實現的原理,就是通過這樣一個動態代理對所有需要事務管理的Bean進行載入,並根據配置在invoke方法中對當前呼叫的 方法名進行判定,並在method.invoke方法前後為其加上合適的事務管理程式碼,這樣就實現了Spring式的事務管理。Spring中的AOP實 現更為複雜和靈活,不過基本原理是一致的。