10

I have created an Aspect which performs a basic id comparison to ensure that a user belongs to a the same group that created the entity being requested. I have had success attaching my aspect to @Service methods, but it doesn't make sense on the service layer, and I need it to be attached to @RestController methods instead. When I attempt to do this, everything seems good, but my Aspect never triggers, and the logs are silent.

pom.xml

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

spring context

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

Aspect

@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;
    }
}

where "doValidationBefore()" and "doValidationAfter()" will throw an exception if validation fails.

And finally, my 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);
    }
}

Some things to note:

  • This exact aspect works when I change the execution pattern to match services and place it in my service package.
  • The Aspect and the RestController are in the same context
  • I use IDEA IDE, and when I use the "navigate to advised methods" icon on the Aspect, the method I'm testing IS listed in the list of methods.
  • None of the methods listed in "navigate to advised methods" are working

Things I have tried:

  • I added 3 libraries to my pom.xml: org.aspectj:aspectjrt:1.8.6, org.aspectj:aspectjtools:1.8.6, cglib:cglib:2.2.2. None of these made any difference.
  • I tried defining my Aspect and PointCuts directly in the context xml and removing the annotations, no difference.
  • I have tried setting my execution pattern to apply to ALL methods, and it still did not trigger.
  • I tried adding an interface for my RestController, no change.

I would love some help here, as I've been trying to solve this for quite some time now. I know it must be possible.

rjdkolb
  • 10,377
  • 11
  • 69
  • 89
Nephthys76
  • 615
  • 2
  • 8
  • 23

2 Answers2

8

As it turns out, my Aspect and my Controllers were NOT, in fact, in the same context.

While I believed my Controllers to be included in the context scanning of my web-context.xml, they were actually being scanned in WEB-INF/servlet-context.xml

Once I moved my Aspect configuration to WEB-INF/servlet-context.xml, my Aspect began to trigger as expected.

Thanks for all those who contemplated my problem.

Nephthys76
  • 615
  • 2
  • 8
  • 23
0

Figure out for sure where your service is being configured in spring. If you have I there is an icon that you can click to navigate to the spring bean config. Then ensure that the aspect is configured in the same file.

If they are definitely defined in the same file, look next that the aop pointcut advice matches the method on which you're expecting it to fire. Again, Idea has an icon next to the pointcut that will navigate to matching methods.