2016-11-08 7 views
1

AOPを使用して、一部のサービスについて監査フレームワークをラップしています。私は再帰のために同じアクションのために複数のイベントを監査するという問題に遭遇しました。メソッドを@NonAuditableとマークし、それを私のpointcut戦略に追加するための簡単な解決策です。私はまだ方法が実行されることを発見している。注釈が存在しない場合はAOPと実行

は、ここに私の既存の戦略です:

@Around(value="(" + 
    "execution(* my.class.services..*.*(..)) " + 
    ") && "+ 
    "@annotation(auditable)), argName="audit") 
    public Object audit(ProceedingJoinPoint call, Audit audit) { 
     ... 
     ... 
    } 

は、どのように私はそれが@NonAuditable注釈が含まれていない場合にのみサービスパッケージ内で実行」と言って、私の実行を更新することができ

を私は次のことを試してみました、?動作しませんでした:

@Around(value="(" + 
"execution(* my.class.services..*.*(..)) " + 
") && "+ 
"[email protected](NonAuditable) && " + 
"@annotation(auditable), argName="audit") 
public Object audit(ProceedingJoinPoint call, Audit audit) { 
    ... 
    ... 
} 

UPDATE:

は、ここで私は継承

package my.class.services.CarService 
import ... 
... 

@Auditable(message="Request for traffic violations", Context="Search") 
public List<Ticket> getTickets(long id){ 
     List<Ticket> tix = dmvRepository.getUserTicketsById(id); 
     ... // do work 
} 

一つの問題\

package my.class.services.UserService 
import ... 
... 

@Auditable(message="Request for user", Context="Search") 
public User getUser(long id){ 
     User u = userRepository.getUser(id); 
     ... // do work 
} 

を監査しますいくつかの方法のいくつかの例ですgetTicketsは、他の方法で再帰的に呼び出されていると私は適用することができるように探していますということですAnnotation@NonAuditable)を使用して、getTicketsの監査を停止します。

+1

私はこの問題を十分に理解していないと思いますが、説明は不明です。どの種類のメソッドを監査するのか、どのメソッドを監査しないのかを示すサンプルコードを追加してください。可能であれば、メソッド、注釈、階層を呼びたいと思っています。 – kriegaex

+0

が更新されました。さらに詳しい情報が必要な場合はお知らせください – Dan

+0

私はまだ理解していません。同じメソッドで '@ Auditable'と' @ NonAuditable'の両方を使いたいのですか?面白いアイデアだが、なぜ?実際に問題を説明するのではなく、おそらくはうまくいかない解決策を意味しています。私はまだあなたが単語で説明する再帰問題をコードには見ません。 – kriegaex

答えて

0

さて、もう一度考えてみて、あなたが何を意味しているかを推測していると思います。

注釈:

package de.scrum_master.app; 

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

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

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

@Retention(RetentionPolicy.RUNTIME) 
public @interface NonAuditable {} 

ドライバアプリケーション:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
     Application application = new Application(); 
     application.auditableAction("main"); 
     application.inBetweenAction("main"); 
     application.otherAction(); 
     application.nonAuditableAction(); 
    } 

    @Auditable 
    public void auditableAction(String caller) { 
     System.out.println(" auditableAction called by " + caller); 
    } 

    @NonAuditable 
    public void nonAuditableAction() { 
     auditableAction("nonAuditableAction"); 
     inBetweenAction("nonAuditableAction"); 
    } 

    public void otherAction() { 
     auditableAction("otherAction"); 
     inBetweenAction("otherAction"); 
    } 

    public void inBetweenAction(String caller) { 
     auditableAction(caller + " via inBetweenAction"); 
    } 
} 

今、私はあなたが@Auditableの監査の実行を回避したいと仮定し、私はあなたの状況がこのようだと思いますメソッドで直接または間接的に呼び出された場合は@NonAuditableメソッドです。正しい?その場合は、cflow()またはcflowbelow() pointcutを使用します。このようなポイントカットは静的に評価することはできず、実行時には動的にしか評価できないため、アスペクトを適用した後にアプリケーションのパフォーマンスを監視する必要がありますが、多くの場合、これは実際の問題ではありません。自分で見て。次のように解決策を探します:

アスペクト比:

package de.scrum_master.aspect; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 

@Aspect 
public class AuditAspect { 
    @Around(
     "within(de.scrum_master.app..*) && " + 
     "execution(* *(..)) && " + 
     "@annotation(de.scrum_master.app.Auditable) && " + 
     "!cflow(@annotation(de.scrum_master.app.NonAuditable))" 
    ) 
    public Object audit(ProceedingJoinPoint thisJoinPoint) throws Throwable { 
     System.out.println(thisJoinPoint); 
     return thisJoinPoint.proceed(); 
    } 
} 

コンソールログ:

execution(void de.scrum_master.app.Application.auditableAction(String)) 
    auditableAction called by main 
execution(void de.scrum_master.app.Application.auditableAction(String)) 
    auditableAction called by main via inBetweenAction 
execution(void de.scrum_master.app.Application.auditableAction(String)) 
    auditableAction called by otherAction 
execution(void de.scrum_master.app.Application.auditableAction(String)) 
    auditableAction called by otherAction via inBetweenAction 
    auditableAction called by nonAuditableAction 
    auditableAction called by nonAuditableAction via inBetweenAction 

は何も最後の2行の前に記録されませんのでご注意ください。

+0

これはIT !!!最後に! – Dan

+0

実行後、サポートされていないポイントカットプリミティブ 'cflow'が含まれています。これらのポイントカットタイプはSpringでサポートされていないためです。回避策に関する考えはありますか? – Dan

+0

もちろん。 Spring AOPの代わりに完全な[AspectJ](http://www.eclipse.org/aspectj/)を使用する必要があります(これは単なるプロキシベースの "AOP Lite"フレームワークです)。 Springマニュアルでは、Spring内からのロード時織りを使用してAspectJを使用する方法について説明しています([11.8 SpringアプリケーションでのAspectJの使用](https://docs.spring.io/spring/docs/current/spring-framework-reference/html) /aop.html#aop-using-aspectj)。また、コンパイル時の織り方を使用することもできます。 – kriegaex

関連する問題