10

ユーザーが要求されているエンティティを作成したのと同じグループに属していることを確認するために、基本的な ID 比較を実行するアスペクトを作成しました。アスペクトを @Service メソッドにアタッチすることに成功しましたが、サービス レイヤーでは意味がなく、代わりに @RestController メソッドにアタッチする必要があります。これを実行しようとすると、すべて問題ないように見えますが、アスペクトがトリガーされず、ログがサイレントになります。

pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.7.RELEASE</version>
</dependency>

春のコンテキスト

<context:annotation-config/>
<context:component-scan base-package="my.pkg"/>
<aop:aspectj-autoproxy/>
<aop:config proxy-target-class="true"/>

側面

@Aspect
@Component
public class MyAspect {
    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void controller() {}

@Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void restController() {}

    @Pointcut("args(java.security.Principal,..)")
    public void principalArgPointcut() {}

    @Around("(controller() || restController()) && principalArgPointcut()")
    public Object validate(ProceedingJoinPoint point) throws Throwable {
        doValidationBefore();
        Object result = point.proceed();
        doValidationAfter();

        return result;
    }
}

「doValidationBefore()」および「doValidationAfter()」は、検証が失敗した場合に例外をスローします。

そして最後に、私の RestController

@RestController
@RequestMapping("/my-path")
public class MyController {
    @RequestMapping(value = "/{entityId}", method = RequestMethod.GET)
    public @ResponseBody
    ResponseEntity<MyEntity> getEntityDetails(Principal principal, @PathVariable("entityId") Long entityId) {
        return new ResponseEntity(HttpStatus.OK);
    }
}

注意すべき点:

  • サービスに合わせて実行パターンを変更し、それをサービス パッケージに配置すると、まさにこの側面が機能します。
  • Aspect と RestController は同じコンテキストにあります
  • 私は IDEA IDE を使用しています。アスペクトの [推奨される方法に移動] アイコンを使用すると、テストしている方法が方法のリストに表示されます。
  • 「推奨される方法に移動する」にリストされている方法はどれも機能していません

私が試したこと:

  • pom.xml に 3 つのライブラリを追加しました: org.aspectj:aspectjrt:1.8.6、org.aspectj:aspectjtools:1.8.6、cglib:cglib:2.2.2。これらのどれも違いはありませんでした。
  • コンテキスト xml で Aspect と PointCuts を直接定義して、注釈を削除しようとしましたが、違いはありません。
  • 実行パターンをすべてのメソッドに適用するように設定しようとしましたが、それでもトリガーされませんでした。
  • RestController のインターフェイスを追加しようとしましたが、変更はありません。

かなり長い間これを解決しようとしてきたので、ここで助けていただければ幸いです。私はそれが可能でなければならないことを知っています。

4

2 に答える 2

8

結局のところ、私のアスペクトとコントローラーは、実際には同じコンテキストにありませんでした。

コントローラーは web-context.xml のコンテキスト スキャンに含まれていると信じていましたが、実際には WEB-INF/servlet-context.xml でスキャンされていました。

アスペクト構成を WEB-INF/servlet-context.xml に移動すると、アスペクトが期待どおりにトリガーされるようになりました。

私の問題を考えてくれたすべての人に感謝します。

于 2015-08-24T17:50:55.797 に答える
0

春にサービスが構成されている場所を確認してください。I をお持ちの場合は、クリックして Spring Bean 構成に移動できるアイコンがあります。次に、アスペクトが同じファイルで構成されていることを確認します。

それらが同じファイルで確実に定義されている場合は、次に、aop ポイントカット アドバイスが、起動することを期待しているメソッドと一致することを確認します。繰り返しますが、Idea には、一致するメソッドに移動するポイントカットの横にアイコンがあります。

于 2016-06-28T19:37:07.647 に答える