简体   繁体   中英

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.

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.

it all seems ok, but you should write a thing like this:

<aop:aspectj-autoproxy >
        <aop:include name="loggedRequestAspect"/>
    </aop:aspectj-autoproxy>

because with this final configuration you say at the spring autoproxy infrastructure what beans consider in the auto proxying process. The key point hear is if you want use the aspect for log the method call, it is fine but if you want use the aspect for log the http call it will be not work, in this case could be a good choice use an interceptor.

You may use a your org.springframework.web.servlet.HandlerInterceptor or org.springframework.web.context.request.WebRequestInterceptor implementations

and then register it in a org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter like this:

@Configuration
class MyWebConfiguratio extends WebMvcConfigurerAdapter {
....
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new HandlerInterceptor() {
               ...
            }).addPathPatterns("....");
            registry.addInterceptor(new WebMvcConfigurerAdapter() {
              ....
            }).addPathPatterns("....");
        }

      ....
}

in java config or

 <mvc:interceptors>
        <bean id="localeChangeInterceptor"
              class="com.yourapp.Interceptor""/>
    </mvc:interceptors>

in your xml configuration file with the mvc namespace

I hope this can help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM