Spring AOP Annotation不起作用

时间:2016-03-08 12:05:18

标签: java spring spring-aop

我有以下方面类:

@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!");
    }
}

对于Annotation类:

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

最后切入点:

public class LoggedRequestPointCut {

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

}

现在可以肯定的是,我在控制器中注释了所需的api方法:

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

...
    }

正如SO上的许多其他答案所表明的那样。我在弹簧配置中添加了以下内容:

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

现在这一切都行不通。我的意思是在/login的API调用中,所需的建议没有执行。

2 个答案:

答案 0 :(得分:2)

在Spring中对bean使用AOP时,只应用于同一应用程序上下文中的bean。

在典型的网络应用程序中,您将拥有ContextLoaderListenerDispatcherServlet,这两者都会创建ApplicationContextContextLoaderListener创建所谓的根应用程序上下文,DispatcherServlet创建与根上下文关系的子上下文。

来自root的AOP配置不会影响子上下文中的bean,子上下文中的AOP配置不会影响根上下文中的bean。

现在,您已在根上下文中配置了方面和<aop:aspectj-autoproxy />,除了它以适用于生成在子上下文中的bean。这显然不会起作用。将该配置移动(或复制)到子上下文中。

另一件事是你需要基于类的代理,因为你没有界面,所以你可能还想将proxy-target-class="true"添加到<aop:aspectj-autoproxy />元素。

答案 1 :(得分:0)

一切似乎都好,但你应该写一个这样的东西:

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

因为有了这个最终配置,你会在spring autoproxy基础设施上说豆在自动代理过程中会考虑什么。 关键点听说如果你想使用方面来记录方法调用,那很好但是如果你想使用方面来记录http调用它将无法工作,在这种情况下使用拦截器可能是一个不错的选择。

您可以使用org.springframework.web.servlet.HandlerInterceptor或org.springframework.web.context.request.WebRequestInterceptor实现

然后将其注册到org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter中,如下所示:

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

      ....
}

在java config或

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

在带有mvc名称空间的

我希望这可以帮到你