簡體   English   中英

如何使用 AspectJ 在 AOP 中創建每個類、每個對象和每個方法/源位置部分的方面

[英]How do you create an aspect with per class, per object and per method/source-location parts in AOP using AspectJ

我想為每個類、每個對象和每個方法/源位置部分創建一個方面實例。

更特別的是:

  • 有些值只在不同的類之間改變,但每個類只需要計算一次,因此每個類需要推導一次。 例如,存儲Class將是每個類,也是對用於Logger的特定類的記錄Logger的引用。
  • 有些值因方法而異,但每個方法只需要計算一次,因此每個方法需要推導一次。 例如,方法簽名將是每個類的每個方法。 此數據不會因對象實例或調用而更改。
  • 某些值從實例/對象更改為實例/對象,但每個實例/對象只需計算一次,因此每個實例/對象需要推導一次。 例如對象 ID,這將取決於實例。
  • 某些值因對象而異,但每個對象每個字段或方法只需要計算一次,因此每個字段或方法每個對象需要推導一次。 例如,方法的調用計數將取決於方法和對象。
  • 有些值會因調用而異,因此需要為每次調用推斷/計算它們。 例如在 AspectJ 中獲取方法參數。 這取決於方法、對象和調用。

我正在嘗試創建存儲這些推導/計算值的方面。 為了不產生超出內存和計算所需的內容。 這如何在 Eclipse AspectJ AOP 中實現?

到目前為止,我一直在嘗試做的是創建這樣的層次結構:

aspect Base {
    // Singleton - data items for the whole program computed and stored once
    // This is shared across all the objects in the application regardless of the class

    protected pointcut executionJoinPoints(): !within(Base+) && execution (* *.*(..));
}

aspect PerClass extends Base perthis(executionJoinPoints()) {
    // Per class - store class-specific data computed and stored once per class
    // Since this is class-specific, need to know what class this corresponds to
    // This is shared across all the objects of the same class
}

aspect PerMethodPerClass extends PerClass percflow(executionJoinPoints()) {
    // Per method - store method specific data computed and stored once per method as fields
    // Since this is method-specific, need to know what method this corresponds to
    // This is shared across all the objects of the same class
}

aspect PerObject extends PerMethodPerClass perthis(executionJoinPoints()) {
    // Per object/instance - store object/instance-specific data computed and stored once per object
    // Since this is object/instance-specific, need to know what object/instance this corresponds to
    // This is specific to the object/instance
}

aspect PerMethodPerObject extends PerObject percflow(executionJoinPoints()) {
    // Per method per object - store method specific data computed and stored once per method as fields for every object instance
    // Since this is method-specific, need to know what method this corresponds to and also what object this corresponds to
    // This is specific to the object/instance and particular method
}


public aspect PerCall extends PerMethodPerInstance {
    // Per call - handle data which change from call to call
    // This is specific to the call or invocation or execution
}

我正在嘗試實施:

  • 日志記錄和跟蹤
  • 程序執行的指標和統計信息收集

使用 AspecJ AOP。 對於統計信息,我收集每個類、每個對象和每個方法/源位置部分需要一個方面實例來存儲和收集相關數據。

例如,與方法相關的統計數據將被計算並存儲在PerMethod方面。 此外,與在大型數據結構中查找相比,查找可訪問實例的特定於方法的計數器會更容易。 這里需要的是為每個方法實例化切面一次。 類、對象等也類似。

收集執行統計數據會產生一些開銷,但在這樣做時,我試圖將其保持在最低限度,因此為什么我想要每個案例的特定方面。

我問這個是為了學習如何在 AspectJ 中做到這一點,而不是試圖解決一個特定的問題。 一旦我嘗試實施它,可能會彈出特定的問題,我可以分享我嘗試過的更具體的例子以及它產生的錯誤或問題。

很抱歉將其寫為答案,但評論太長了。

這個問題的問題在於,盡管有廣泛的解釋,但您只解釋您希望如何在技​​術上做某事,甚至一次都沒有說您要解決的問題是什么 這使得這個問題成為XY 問題的一個很好的例子。

  • 你的方面是做什么的?
  • 您是否遇到內存或性能問題?
  • 您確定不是與建議代碼相結合的廣泛的全面切入點 - 在前面的問題中,您想詳細記錄每個方法執行的所有內容,模擬某種調試器 - 是問題嗎?
  • 你有問題嗎? 如果是這樣,你沒有說明。 您可能只是在進行過早的優化。

您正在嘗試節省內存和 CPU 周期,我從您的問題中得到了這一點。

  • 您是否知道這樣一個事實:通過嘗試這樣做,您正在通過per...子句創建許多方面實例,而不是使用默認的 AspectJ 單例方面實例化模型?
  • 你有沒有衡量這是否會讓事情變得更好,而不是更糟?

實際上,您的問題並沒有提出真正的問題,您正在展示一個方面的層次結構,絕對沒有做任何事情。 所以這樣的問題格式與 StackOverflow 不兼容。 這是一個問答平台,而不是一個討論論壇。 我通過實際提問而不是為您的問題提出解決方案來回答已經是它的一個症狀。 固執己見的辯論正是 SO 不適合的。 所以就像我之前在其他問題中所說的:提問的最佳方式是提供MCVE和清晰的問題描述,其他人可以運行並重現您的問題的代碼。


更新:正如您在 AspectJ 手冊中所見,有以下方面實例化類型

  • 單身人士
  • 每個對象( perthis()pertarget()這對於call()切入點是不同的,但對於execution()應該是相同的)
  • 每個控制流( percflow()percflowbelow()
  • 每個類型( pertypewithin()在此處描述)

請注意,“每個控制流”與“每個方法”不同。 如文檔所述,每次進入某個控制流時,例如每次執行一個方法時,都會創建一個方面實例。 如果相同的方法執行 12,345 次,則將創建 12.345 個方面實例。 因此,如果您希望收集每個方法的統計信息,最好將信息存儲在相應類的每個類型方面實例中。 對於您的“每次調用”要求,我認為“每個控制流”建議是合適的。

現在我們完成了。 就像我說的,如果你想在這里討論你的應用程序設計理念,這是錯誤的地方。 因此,我將在此停止回復,並等待您通過 MCVE 提出具體的新問題,這些問題可以清楚正確地回答,而不是引發討論。 我現在盡可能多地提供幫助,比我應該提供的更多,因為這個問題實際上應該作為離題的 IMO 關閉。

祝你的有趣項目好運。 如果您需要更多咨詢,我也將其作為日常工作來做,當然,您可以雇用我。 ;-)

否則,我想鼓勵你通過實施一些東西來創造可驗證的事實,而不是在這里提出一大堆理論問題(我現在已經回答了其中的 3 個),然后看看你的想法是否有效。 你似乎喜歡推理。 思考是好的,但做也是如此。 使用兩者,您將取得更多進展並反復(in-)驗證您的想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM