10

我创建了一个执行基本 id 比较的 Aspect,以确保用户属于创建所请求实体的同一组。我已经成功地将我的方面附加到 @Service 方法,但它在服务层没有意义,我需要将它附加到 @RestController 方法。当我尝试这样做时,一切似乎都很好,但我的 Aspect 从未触发,并且日志是静默的。

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,当我使用 Aspect 上的“导航到建议的方法”图标时,我正在测试的方法列在方法列表中。
  • “导航到建议的方法”中列出的所有方法都不起作用

我尝试过的事情:

  • 我在 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

事实证明,我的 Aspect 和我的控制器实际上不在同一个上下文中。

虽然我相信我的控制器包含在我的 web-context.xml 的上下文扫描中,但它们实际上是在 WEB-INF/servlet-context.xml 中进行扫描的

一旦我将我的 Aspect 配置移动到 WEB-INF/servlet-context.xml,我的 Aspect 就开始按预期触发。

感谢所有考虑我问题的人。

于 2015-08-24T17:50:55.797 回答
0

确定您的服务在春季配置的位置。如果你有我有一个图标,你可以点击它来导航到 spring bean 配置。然后确保在同一个文件中配置方面。

如果它们确实定义在同一个文件中,接下来查看 aop 切入点建议是否与您期望它触发的方法匹配。同样,Idea 在切入点旁边有一个图标,它将导航到匹配的方法。

于 2016-06-28T19:37:07.647 回答