程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Spring事務處理及其AOP框架的內幕

Spring事務處理及其AOP框架的內幕

編輯:關於JAVA

Spring框架中成功吸引人的一點就是容器事務的管理,提供了一個輕量級的容器事務處理,針對的對象是普通的java類,使用Spring事務管理的話,你可以按照自己的業務把一些相關的方法納入其事務管理裡面,這就避免了程序員在處理事務的過程中繁瑣的工作.同時這些也是ejb2.X規范裡面吸引人的一點,這在spring裡面都很好的提供.雖然在跨容器的事務管理,spring裡面並沒有提供,但是對於一般的web程序來說,也不需要僅僅為了那些功能而不得不使用ejb。不過,最近jboss的嵌入式的ejb容器也可以做的更小了,也是開源中的選擇之一.無論技術是怎樣發展的,當前,我們先來研究其中AOP實現的方法。

事實上,Spring中的事務處理是通過AOP思想來實現的,Spring AOP與Aspect J和JBoss具有很大的不同,首先,使用Spring AOP框架的用戶要記住的一點是,Spring AOP針對的是方法層次上的實現,而其他兩者對字段也提供了支持.說到Spring AOP的內幕,其實也不難,對於有接口的類,使用的是Java內部類提供的Proxy;而對於那些不實現接口的類,使用的是cglib庫,動態創建一個子類來實現.

在Spring AOP中提供了4種處理切入類型:around,before,after,introduction.

1)around是針對具體的某個切入點的方法(比如,現在有個OrderBook方法,around的切入類型是就這個方法的內部調用,是通過java的元數據,在運行時通過Method.invoke來調用,具有返回值,當發生意外的時候會終止.記住的一點是,返回值.);

2)before是在方法調用前調用(在OrderBook方法前調用,但是沒有返回值,同時在通常意外情況下,會繼續運行下一步方法.記住的一點是沒有返回值);

3)after和before剛好相反,沒有什麼特別的地方.

4)introduction是一個更加特殊的,但功能更加強大的切入類型.比如(你現在有Book對象,Computer對象,還有幾十個這種業務對象,現在你希望在每個這樣的對象中都加入一個記錄最後修改的時間.但是你又不希望對每個類都進行修改,因為太麻煩了,同時更重要的一點,破壞了對象的完整性,說不定你以後又不需要這個時間數據了呢...這時怎麼辦呢?Spring AOP就為你專門實現這種思想提供了一個切入處理,那就是introduction.introduction可以為你動態加入某些方法,這樣可以在運行時,強制轉換這些對象,進行插入時間數據的動作,更深的內幕就是C++虛函數中的vtable思想).不過這種動態是以性能作為代價的,使用之前要慎重考慮,這裡我們談的是技術,所以就認為他是必需的。

好,現在我們就拿第四種來進行舉例說明Spring AOP的強大之處:

1)假設創建了一個BookService接口及其實現方法(你自己的業務對象):

//?$ID:BookService.java Created:2005-11-6 by Kerluse Benn
package com.osiris.springaop;
public interface BookService {
  public String OrderComputerMagazine(String userName,String bookName);
  public String OrderBook(String userName,String bookName);
}
//?$ID:BookServiceImpl.java Created:2005-11-6 by Kerluse Benn
package com.osiris.springaop;
public class BookServiceImpl implements BookService{
  public String OrderBook(String name,String bookName) {
   // TODO Add your codes here
   String result=null;
   result="訂購"+bookName+"成功";
   return result;
  }
  public String OrderComputerMagazine(String userName, String bookName) {
   // TODO Add your codes here
   String result=null;
   result="訂購"+bookName+"成功";
   return result;
  }
}

2) 事實上你還有很多這樣的對象,現在我們希望在每個對象中添加我們的功能最後修改的時間,功能如下:

//?$ID:IAuditable.java Created:2005-11-7 by Kerluse Benn
package com.osiris.springaop.advices.intruduction;
import java.util.Date;
public interface IAuditable {
  void setLastModifiedDate(Date date);
  Date getLastModifiedDate();
}

3) 因為我們使用的切入類型是introduction,Spring AOP為我們提供了一個描述這種類型的接口IntroductionInterceptor,所以我們的切入實現處理,也需要實現這個接口:

//?$ID:AuditableMixin.java Created:2005-11-7 by Kerluse Benn
package com.osiris.springaop.advices.intruduction;
import java.util.Date;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;
public class AuditableMixin implements IAuditable,IntroductionInterceptor{
  private Date lastModifiedDate;
  public Object invoke(MethodInvocation m) throws Throwable {
   // TODO Add your codes here
   if(implementsInterface(m.getMethod().getDeclaringClass())){
    return m.getMethod().invoke(this,m.getArguments());
    //invoke introduced mthod,here is IAuditable
   }else{
    return m.proceed(); //delegate other method
   }
  }
  public Date getLastModifiedDate() {
   // TODO Add your codes here
   return lastModifiedDate;
  }
  public void setLastModifiedDate(Date date) {
   // TODO Add your codes here
   lastModifiedDate=date;
  }
  public boolean implementsInterface(Class cls) {
   // TODO Add your codes here
   return cls.isAssignableFrom(IAuditable.class);
  }
}

輸出結果:

訂購Professional C#成功 訂購時間為Mon Nov 07 11:35:20 CST 2005

訂購Expert j2ee one-on-one成功 訂購時間為Mon Nov 07 11:35:30 CST 2005

看見上面黑體字:

IAuditable auditable=(IAuditable)bookService;

由於bookService對象事實上已經實現了IAuditable接口,通過Spring AOP的introduction切入實現,所以在運行時(熟悉C++的vtable模型的可以在大腦裡想一下)可以轉換,我們就可以隨意添加自己的接口方法了。

好了,關於Spring AOP就介紹到這了,其他相關的內容可以參考相應的書籍,這篇文章的目的主要是為了介紹一下AOP思想應用的強大之處.具體的相關應用還包括用戶操作驗證等等。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved