熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

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

2013-11-23 20:33:12  來源: Java開源技術 

  ***注:非入門者讀***
  
  Spring框架中成功吸引人的一點就是容器事務的管理提供了一個輕量級的容器事務處理針對的對象是普通的java類使用Spring事務管理的話你可以按照自己的業務把一些相關的方法納入其事務管理裡面這就避免了程序員在處理事務的過程中繁瑣的工作同時這些也是ejbX規范裡面吸引人的一點這在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中提供了種處理切入類型:aroundbeforeafterintroduction顧名思義
  
  )around是針對具體的某個切入點的方法(比如現在有個OrderBook方法around的切入類型是就這個方法的內部調用是通過java的元數據在運行時通過Methodinvoke來調用具有返回值當發生意外的時候會終止記住的一點是返回值);
  
  )before是在方法調用前調用(在OrderBook方法前調用但是沒有返回值同時在通常意外情況下會繼續運行下一步方法記住的一點是沒有返回值);
  
  )after和before剛好相反沒有什麼特別的地方
  
  )introduction是一個更加特殊的但功能更加強大的切入類型比如(你現在有Book對象Computer對象還有幾十個這種業務對象現在你希望在每個這樣的對象中都加入一個記錄最後修改的時間但是你又不希望對每個類都進行修改因為太麻煩了同時更重要的一點破壞了對象的完整性說不定你以後又不需要這個時間數據了呢這時怎麼辦呢?Spring AOP就為你專門實現這種思想提供了一個切入處理那就是introductionintroduction可以為你動態加入某些方法這樣可以在運行時強制轉換這些對象進行插入時間數據的動作更深的內幕就是C++虛函數中的vtable思想)不過這種動態是以性能作為代價的使用之前要慎重考慮這裡我們談的是技術所以就認為他是必需的
  
  好現在我們就拿第四種來進行舉例說明Spring AOP的強大之處:
  
  )假設創建了一個BookService接口及其實現方法(你自己的業務對象):
  
  //$ID:BookServicejava Created: by Kerluse Benn
  package comosirisspringaop;
  
  public interface BookService {
  public String OrderComputerMagazine(String userNameString bookName);
  public String OrderBook(String userNameString bookName);
  }
  
  //$ID:BookServiceImpljava Created: by Kerluse Benn
  package comosirisspringaop;
  
  public class BookServiceImpl implements BookService{
  public String OrderBook(String nameString 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;
  }
  }
  
  )事實上你還有很多這樣的對象現在我們希望在每個對象中添加我們的功能最後修改的時間功能如下:
  
  //$ID:IAuditablejava Created: by Kerluse Benn
  package comosirisspringaopadvicesintruduction;
  
  import javautilDate;
  
  public interface IAuditable {
  void setLastModifiedDate(Date date);
  Date getLastModifiedDate();
  }
  
  )因為我們使用的切入類型是introductionSpring AOP為我們提供了一個描述這種類型的接口IntroductionInterceptor所以我們的切入實現處理也需要實現這個接口:
  
  //$ID:AuditableMixinjava Created: by Kerluse Benn
  package comosirisspringaopadvicesintruduction;
  
  import javautilDate;
  
  import orgaopallianceinterceptMethodInvocation;
  import orgspringframeworkaopIntroductionInterceptor;
  
  public class AuditableMixin implements IAuditableIntroductionInterceptor{
  private Date lastModifiedDate;
  
  public Object invoke(MethodInvocation m) throws Throwable {
  // TODO Add your codes here
  if(implementsInterface(mgetMethod()getDeclaringClass())){
  return mgetMethod()invoke(thismgetArguments());
  //invoke introduced mthodhere is IAuditable
  }else{
  return mproceed(); //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 clsisAssignableFrom(IAuditableclass);
  }
  
  }
  
  )ok現在業務對象BookService類有了自己希望添加的處理也有了IAuditable那就剩下使用Spring AOP框架的問題了配置beanxml文件:
  
  <?xml version= encoding=UTF?>
  <!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beansdtd>
  <beans>
  <! Beans >
  <bean id=BookServiceTarget class=comosirisspringaopBookServiceImpl singleton=false/>
  
  <! introduction advice >
  <bean id=AuditableMixin class=comosirisspringaopadvicesintruductionAuditableMixin singleton=false/>
  
  <! Introduction advisor >
  <bean id=AuditableAdvisor class=orgspringframeworkaopsupportDefaultIntroductionAdvisor
  singleton=false>
  <constructorarg>
  <ref bean=AuditableMixin/>
  </constructorarg>
  </bean>
  
  <bean id=BookService class=orgspringframeworkaopframeworkProxyFactoryBean>
  <property name=target>
  <ref bean=BookServiceTarget/>
  </property>
  
  <property name=singleton>
  <value>false</value>
  </property>
  
  <! force to use cglib >
  <property name=proxyTargetClass>
  <value>true</value>
  </property>
  
  <! introduction methods >
  <property name=proxyInterfaces>
  <value>comosirisspringaopadvicesintruductionIAuditable</value>
  </property>
  
  <property name=interceptorNames>
  <list>
  <value>AuditableAdvisor</value>
  </list>
  </property>
  </bean>
  
  </beans>
  
  以上就是配置文件現在我們假設使用業務對象如下這裡是一個簡單測試類:
  
  //$ID:MainAppjava Created: by Kerluse Benn
  package comosirisspringaop;
  
  import javautilDate;
  
  import orgspringframeworkbeansfactoryBeanFactory;
  import orgspringframeworkbeansfactoryxmlXmlBeanFactory;
  import orgreioFileSystemResource;
  
  import comosirisspringaopadvicesintruductionIAuditable;
  
  public class MainApp {
  /**
  * @param args
  * @author Kerluse Benn
  */
  public static void main(String[] args) throws Exception{
  // TODO Add your codes here
  BeanFactory factory=new XmlBeanFactory(new FileSystemResource(beanxml));
  BookService bookService=(BookService)factorygetBean(BookService);
  IAuditable auditable=(IAuditable)bookService;
  Systemoutprint(bookServiceOrderBook(Kerluse BennProfessional C#));
  auditablesetLastModifiedDate(new Date());
  Systemoutprintln( 訂購時間為+auditablegetLastModifiedDate());
  Threadsleep();
  Systemoutprint(bookServiceOrderBook(Kerluse BennExpert jee oneonone));
  auditablesetLastModifiedDate(new Date());
  System
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28652.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.