2012-06-08 75 views
2

我真的開始圍繞AOP包裝頭腦,並且非常喜歡抽象出橫切關注點並將其從我的核心業務代碼中移除的想法。到目前爲止,我一直在閱讀AOP聯盟(我認爲它是Guice和Spring AOP的主力)和AspectJ。以AOP爲基礎的持久性,交易和消息示例

不幸的是,當我們談論比簡單方法攔截更高級的任何事情時,很好的工作Java AOP代碼示例很難實現。我一直在反覆閱讀如何使用AOP實現持久性,事務處理和消息傳遞等主要Java EE概念,但在我的生活中,我找不到任何這樣的例子!最終,在一天結束時,AOP只會歸結爲方法攔截(除非我在這裏丟失了一些主要)。所以,如果是這樣的話,並給予一個方法攔截器的一般形式:

// Using AOP Alliance for this example 
public class MyInterceptor implements MethodInterceptor { 
    public Object invoke(MethodInvocation inv) { 
     // Run this code before executing inv. 
     preInvocation(); 

     Object result = inv.proceed(); 

     // Run this code after executing inv. 
     postInvocation(); 
    } 

    // ... 
} 

假設爲出發點,有人可以如何各自的這些Java EE概念可以委託提供具體代碼示例到AOP經由方法截獲:

  • 持久性/ ORM
  • 事務處理
  • 消息

我想我只是難以連接所有的點,並通過「樹」看到「森林」。提前致謝!

+0

令人興奮,因爲AOP可以在第一,只是小心的「AUTOMAGIC」的後果代碼...我們已經發現它可以讓人非常沮喪/混淆到你的團隊其他開發人員不必爲它的一個句柄的固體。就像所有的事情一樣,它適可而止。 – jkschneider

+0

我真的推薦使用註釋來代替純粹的代碼AOP編織,但它更容易遵循。對此有任何興趣,或者你真的在尋找一個帶有交易信息的線程局部變量存在的例子嗎?我不確定AOP會給信息添加什麼,你在那裏尋找什麼? – stevedbrown

+0

我是*品牌*新的AOP,並試圖查看我一直在[閱讀](http://en.wikipedia.org/wiki/Cross-cutting_concern)的工作代碼示例。是的,我絕對想要結束使用註釋(方法攔截),而不是字節碼編織有幾個原因。我正在尋找的是一個AOP方法攔截器的例子,它可以用於持久性或消息傳遞(也就是說,當一個方法執行時,它被攔截,某種類型的持久化或面向消息傳遞的代碼作爲它的建議執行)。 – IAmYourFaja

回答

3

不知道持久性和消息傳遞,但對於交易,我可以解釋。我將以Spring爲例。

您可以配置Spring bean(通常是服務層bean),以便在這些bean上調用的每個方法都將被事務攔截器攔截。這個攔截器通常做以下的事情:

  • 看到,如果一個交易已經綁定到當前線程
  • 如果不是,啓動一個事務,並將其綁定到當前線程
  • 調用方法
  • 如果事務是通過此方法攔截啓動的,並且此方法未引發運行時異常,則提交事務
  • 如果事務是由此方法攔截啓動的,並且該方法拋出了運行時異常,則回滾事務
  • 從當前線程

不具有事務方面解除綁定交易的交易方法就必須做這樣的事情:

try { 
    userTransaction.begin(); 
    executeSomeBusinessCode(); 
    userTransaction.commit(); 
} 
catch (RuntimeException e) { 
    userTransaction.rollback(); 
} 

這是繁瑣,容易出錯,甚至不處理交易傳播,新交易等。

使用AOP,該方法的主體就變成了:

executeSomeBusinessCode(); 
+0

謝謝@JB。 +1爲卓越的事務示例,但我正在尋找持久性和消息示例,迄今爲止還沒有提供。 – IAmYourFaja

1

不知道你是什麼意思的「消息」和「持久」 - 你要送什麼消息?你想堅持什麼?

如果你想堅持的方法調用的結果它非常直截了當,實現一個MethodInterceptor:

public Object invoke(MethodInvocation invocation) throws Throwable { 
    Object result = invocation.proceed(); 
    myPersistenceMethod(invocation, result); 
    return result; 
} 

然後你就可以定義一個註釋,並有方法的結果持續了註解的方法。例如。在吉斯模塊:

bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyPersistenceAnnotation.class), 
      new MyPersistenceInterceptor()); 

的主要問題是如何構建你的持久「鑰匙」 - 最明顯的事情是你調用方法和參數,但由於這是基於所有的反射也沒有編譯時檢查你是否開始假設某些方法具有某些參數。

如何幫助。