2017-03-06 11 views
1
@Before(value="@annotation(com.aspect.Loggable)",argNames="taskId") 

public void logEmail(JoinPoint joinPoint) { 

    System.out.println("@Before is running!"); 
    System.out.println("hijacked : " + joinPoint.getSignature().getName()); 
    System.out.println("******"); 
} 

の注釈を取得するにはどのように私は、カスタム注釈付きメソッドsendEmail()にポイントカットを持っています。春AOPは - 親(呼び出し側)メソッド

このメソッドsendEmail()は、アプリケーションでdiffernt locationから呼び出されます。

お支払いが承認された場合は、paymentApproved() paymentManagerの方法からsendEmailを呼び出します。 タスクが完了したら、sendMailをtaskComplete()というtaskMangerのメソッドから呼び出します。

私はsendEmailがトリガーされたイベントを見つける必要があります。

paymentManagerのpaymentApproved()にカスタム注釈@EVENT("PAYMENT")を、taskComplete()のtaskMangerに@EVENT("TASK")を適用しました。

@EVENTの値を​​のアスペクトにするにはどうすればよいですか。

答えて

0

パラメータとして受け取ったアノテーションにアクセスできます。このような何か:

@Before(value="@annotation(EVENT)",argNames="taskId") 

public void logEmail(JoinPoint joinPoint, Event event) { 

    // do what you need with event. For example, if the field is called value you can do this: 
    if ("PAYMENT".equals(event.value())) { 
     // do sth 
    } 

    System.out.println("@Before is running!"); 
    System.out.println("hijacked : " + joinPoint.getSignature().getName()); 
    System.out.println("******"); 
} 
+0

これはOPの質問に対する答えではありません。彼は、 'sendEmail'が実行されている他のjoinpointからイベント注釈を取得したいとします。 – kriegaex

+0

もしそれが間違っていると分からなければ、彼は 'sendEmail'と呼ばれるメソッドで同じアノテーションを使用しています。この注釈のポイントカットは – mlg

+0

です。間違っていると分かりました。彼は 'sendEmail'にポイントカットをまだ残しておき、そこから呼び出し側の注釈にアクセスしたいと考えています。私は、呼び出し元メソッドへのpointcutの変更も間接的な方法で問題を解決することを知っていますが、電子メールメソッドを呼び出すことはありませんが、何か他のことをするイベント注釈をメソッドに注釈を付けるとどうなりますか?私の今後の解決策を見てください。 – kriegaex

1

足場:

申し訳ありませんが、私はすべて大文字のクラス名を好きではないと私のテンプレートが既にそれらを生成するので、私はまた、例として、私自身のパッケージ名を使用していました。

package de.scrum_master.app; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Loggable {} 
package de.scrum_master.app; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Event { 
    String value(); 
} 

ドライバアプリケーション:私は春のユーザーではないですので

これはピュアJavaです。ただそれが1つ以上の@Componentであると想像してください。

sendEmail()は、@Eventによって注釈が付けられたメソッドから呼び出されないことに注意してください。これは、アノテートされたメソッドからの2つの呼び出しだけを、アスペクトを引き起こすべきではありません。

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
    Application application = new Application(); 
    application.doSomething(); 
    application.paymentApproved(); 
    application.taskComplete(); 
    } 

    public void doSomething() { 
    sendEmail(); 
    } 

    @Event("paymentApproved") 
    public void paymentApproved() { 
    sendEmail(); 
    } 

    @Event("taskComplete") 
    public void taskComplete() { 
    sendEmail(); 
    } 

    @Loggable 
    public void sendEmail() {} 
} 

アスペクト比:

あなたのポイントカットを表現したい:@Eventによる注釈付きメソッドの制御フロー内@Loggableでアノテートキャッチ方法。制御フローは、cflow()またはcflowbelow()ポイントカットで表すことができます。

package de.scrum_master.aspect; 

import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 

import de.scrum_master.app.Event; 

@Aspect 
public class LogAspect { 
    @Before(
    "@annotation(de.scrum_master.app.Loggable) &&" + 
    "execution(* *(..)) &&" + // only needed for AspectJ, not for Spring AOP 
    "cflow(@annotation(event))" 
) 
    public void logEmail(JoinPoint thisJoinPoint, Event event) { 
    System.out.println(thisJoinPoint + " -> " + event); 
    } 
} 

コンソールログは:

execution(void de.scrum_master.app.Application.sendEmail()) -> @de.scrum_master.app.Event(value=paymentApproved) 
execution(void de.scrum_master.app.Application.sendEmail()) -> @de.scrum_master.app.Event(value=taskComplete) 

更新:あなたがフルにAspectJを使用していた場合(例えば、ロード時間織り経由)の代わりに春AOPのは、あなただけ使うことができましたa call() pointcutそしてそこから、囲みジョインポイントの静的情報が得られます。その後、@Event注釈は必要ではありませんでした。しかし、Spring AOPはちょうど "AOP lite"であり、call()をサポートしていません。

+0

こんにちはkriegaex応答のおかげで:これは私が必要としているが、 "cflow"のために私にエラーを与える: "サポートされていないpointcutプリミティブ 'cflow'"。 私が検索するspringは、このaspectJのサポートのみをサポートしていません。 –

+1

はい、私はSpring AOPを使用していないので、それについて忘れました。しかし、 'cflow()'が必要な場合でも、Springアプリケーション内からAspectJ LTWを使用することができます。 [この章](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-using-aspectj)では、設定方法について説明しています。私が言ったように:春のAOPは "AOPライト"です。 ;-) Spring AOPに固執したい場合は、@ mlgの間接的な解決法を選択することもできます。 – kriegaex

関連する問題