2015-12-12 97 views
1

我想了解AspectJ。我想嘗試在項目中計算所有的對象初始化(它們是從我指定的類中初始化的,而不是一些Java內部的),我真的不知道該怎麼做。AspectJ:跟蹤新的對象初始化

假設我有類A和B,其中A具有Aa和Ab的子類,B具有Ba和Bb的子類,Bb具有Bba的子類。我希望我的方面能夠跟蹤每個以這些類創建的對象的初始化爲基礎,但我並不真正瞭解如何正確地執行此操作(即使這應該有點簡單)。到目前爲止,我有一些與此類似:

public aspect AspectCounter { 
     private int objects = 0; 

     pointcut countObjects() : initialization(A.new(..)) || initialization(B.new(..)); 

     pointcut printObjects() : call(* Test.printCounter(..)); 

     after() : countObjects() { 
      objects++; 
     } 

     after() : printObjects() { 
      System.out.println(objects); 
     } 
} 

這不,至少,打印和B的我創建適量(我沒跟B *。新進入(..)因爲它會按照我理解的方式跟蹤Bba的三次初始化,在這種情況下我不想要)。 它現在的工作方式是我有一個測試類,它測試了一些東西,在完成測試後,我只是調用一個空的printCounter方法,它並沒有做任何事情。它似乎工作,並確實給我正確的數量的對象,但我相信有更好的方法來做到這一點。我真的不喜歡有一個空的方法。

回答

1

由於*.new(..)的執行順序,您不能使用initializationpreinitializationexecution切入點執行此操作。它們不是按照您的想法嵌套,而是由於JVM的工作方式而按順序執行。我已經詳細解釋了這個問題here,包括示例代碼和日誌輸出。所以你只剩下選擇使用call切入點。下面是一個例子:

package de.scrum_master.app; 

public class A {} 
package de.scrum_master.app; 

public class Aa extends A {} 
package de.scrum_master.app; 

public class Ab extends A {} 
package de.scrum_master.app; 

public class B {} 
package de.scrum_master.app; 

public class Ba extends B {} 
package de.scrum_master.app; 

public class Bb extends B {} 
package de.scrum_master.app; 

public class Bba extends Bb {} 

驅動應用:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
     new A(); 
     new Aa(); 
     new Ab(); 
     new B(); 
     new Ba(); 
     new Bb(); 
     new Bba(); 
    } 
} 

看點:

package de.scrum_master.aspect; 

import de.scrum_master.app.A; 
import de.scrum_master.app.B; 

public aspect InstanceCreationCounter { 
    private static int count; 

    after() : call(A+.new(..)) || call(B+.new(..)) { 
     System.out.printf("%4d %s%n", ++count, thisJoinPoint); 
    } 
} 

控制檯日誌:

1 call(de.scrum_master.app.A()) 
    2 call(de.scrum_master.app.Aa()) 
    3 call(de.scrum_master.app.Ab()) 
    4 call(de.scrum_master.app.B()) 
    5 call(de.scrum_master.app.Ba()) 
    6 call(de.scrum_master.app.Bb()) 
    7 call(de.scrum_master.app.Bba()) 

我想這是你想要的。

注意事項:您需要控制所有的調用代碼,並將其編入其中才能使其工作。