Search code examples
javaspringspring-aop

Spring AOP Annotation not working


I have following aspect class:

@Component
@Aspect
public class LoggedRequestAspect {

    private static final Logger LOG = LoggerFactory.getLogger(LoggedRequestAspect.class);

    @Before("com.application.aspect.pointcut.LoggedRequestPointCut.LogRequest()")
    public void logRequest(){
        System.out.println("Method Executed!");
        LOG.debug("Method Executed!");
    }
}

And for Annotation class:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoggedRequest {
}

And finally pointcut:

public class LoggedRequestPointCut {

    @Pointcut("execution(@com.application.aspect.annotation.LoggedRequest * *(..))")
    public void LogRequest(){}

}

Now for sure, I have annotated the required api method in my controller:

...
    @LoggedRequest
    @RequestMapping(value = "/login", method = { RequestMethod.POST })
    public @ResponseBody Map<String, Object> login(/* Param List*/){

...
    }

As suggested by many other answers on SO. I have added following to my spring configuration:

<context:annotation-config/>
...
<context:component-scan base-package="com.application.core"/>
...
<aop:aspectj-autoproxy />

Now All this is not working. I mean on my API call of /login the required advice is not executing.


Solution

  • When using AOP on beans in Spring that is only applied to beans in the same application context.

    In a typical web application you would have a ContextLoaderListener and a DispatcherServlet both of which create an ApplicationContext. The ContextLoaderListener creates the so called root application context and the DispatcherServlet a child context with a relation to the root context.

    AOP configuration from the root doesn't influence beans in the child context and AOP configuration in the child context doesn't influence beans in the root context.

    Now you have configured the aspect and <aop:aspectj-autoproxy /> in the root context and except it to work for a bean that lives in the child context. That obviously isn't going to work. Move (or duplicate) that configuration into the child context.

    Another thing is you will need class based proxies as yu don't have an interface, so you probably also want to add proxy-target-class="true" to the <aop:aspectj-autoproxy /> element.