2016-09-08 5 views
4

次のコードスニペットでは、プロパティmyListにアクセスするたびにロジックを実行する必要があります。出来ますか?AspectJを使用してJavaクラスの静的プロパティをインターセプトする方法はありますか?

public class Test { 
    public static List<String> myList = new ArrayList(); 

    public static void addData(){ 
     myList.add("foo"); 
     myList.add("bar"); 
    } 
    public static void removeData(){ 
     if(myList.size() > 0){ 
      myList.remove(0); 
     } 
    } 
    public static void displayData(){ 
     for (String data : myList) { 
      System.out.println("data : "+data); 
     } 
    } 

    public static void main(String[] args) { 
     addData(); 
     displayData(); 
     removeData(); 
     displayData(); 
    } 
} 
+0

myListをプライベートにして、すべてのアクセサがクラス内にある場合は、それ以外の場合は、実行時にmyListのメモリアドレスを見つけて、デバッガのようにハードウェアブレークポイントを設定する必要があります。 –

+0

プライベートプロパティで、すべてのアクセサが同じクラスにあるとしましょう。次に、傍受のコードサンプルを手伝ってもらえますか? – ashishakp

答えて

1

あなたがコード織ることができBefore/After/Around次のポイントカット使用して、フィールドへのアクセス:

public aspect TestAccessorsAspect { 

    pointcut readMyList() : get(java.util.List com.sample.Test.myList); 

    pointcut writeMyList() : set(java.util.List com.sample.Test.myList); 
} 
:.aj構文で

@Aspect 
public class TestAccessorsAspect { 
    @Pointcut("get(java.util.List com.sample.Test.myList)") 
    public void readMyList(){} 

    @Pointcut("set(java.util.List com.sample.Test.myList)") 
    public void writeMyList(){} 
} 

が、これは次のようになります。

これらのフィールドが読み込み(書き込み)のためにアクセスされるたびに、それらのポイントカットがトリガーされます。

+0

この問題を解決するために、アスペクト指向プログラミングの複雑さを追加する必要はありません。アスペクトは実際には複数のクラスにまたがることを意味します。 OPには1つのクラスがあります。 –

+1

質問が 'aop'と' aspectj'の両方でタグ付けされたので、私は著者が側面を使って答えを求めていると仮定しました。 – XGouchet

+0

はい私はAOPの概念を使用する必要があります、それは要件です。私はちょうど実際のコードに似た何かのサンプルコードを与えました。ところで、皆さんにお返事いただきましてありがとうございます。 – ashishakp

0

あなたの質問は、私がそれを理解しているかわからないほど単純です。あなたが言ったことから、非常に小さな調整がそれに答えます。

public class Test { 
    private static List<String> myList = new ArrayList(); 

    public static void addData() { 
     myListAccessLogic(); 
     myList.add("foo"); 

     myListAccessLogic(); 
     myList.add("bar"); 
    } 
    public static void removeData() { 
     myListAccessLogic(); 
     if(myList.size() > 0) { 

      myListAccessLogic(); 
      myList.remove(0); 
     } 
    } 
    public static void displayData() { 
     myListAccessLogic(); 
     for (String data : myList) { 

      myListAccessLogic(); 
      System.out.println("data : "+data); 
     } 
    } 

    public static void main(String[] args) { 
     addData(); 
     displayData(); 
     removeData(); 
     displayData(); 
    } 
} 
+0

まあ、正確なシナリオを説明しましょう。私はJARがすでに利用可能で、ログインユーザーデータを保持するための静的プロパティ(Arrayクラスの 'User class')を持つクラス(SessionManager)を含んでいます。新しいユーザーがリストに追加されたとき、私は傍受し、リストに追加する前にそのオブジェクトにいくつかの追加情報を追加する必要があります。同様に、そのオブジェクトにアクセスしている間、私はすでに格納されている(余分な)情報を取り出し、特定の操作を実行します。 PS:JARにはソース(.javaファイル)ではなく.classファイルが含まれており、そのJAR内の何かを変更することはできません。 – ashishakp

+0

ArrayListが一般に公開されているため、まだ知らないパスからArrayListにアクセスする可能性のあるJARの内部にコードがあるため、大きな違いがあります。最初に気づくべきことは、ソースを暗号化しない限り、JAR - > javaデコンパイラの1つを使用することができます。これは、ほとんど何をしてArrayListにアクセスしているかを示すことになります。私はMac上でjd-guiを使います:http://jd.benow.caですが、Javaであるため、どこからでも実行できます。それを行い、あなたが制御していないArrayListがどのようにアクセスされているのか教えてください。 –

+0

はい@ダニエル、私は同じことをやって、SessionManagerクラスとUserクラスについて知る必要があります。そのリストの使い方は次のとおりです。ユーザーがアプリケーションに正常にログインすると、そのリストにuserId、userName、sessionIdなどのユーザーの詳細が格納されます。同じユーザーが他のユーザーからログインしようとするとブラウザ/システムで、前のセッションをオンにしている間、メッセージをブロックしている。 – ashishakp

関連する問題