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實 現更為復雜和靈活,不過基本原理是一致的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM