我有以下方面的类:
@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!");
}
}
对于注解类:
@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的回答所建议的那样,我在Spring配置中增加了以下内容:
<context:annotation-config/>
...
<context:component-scan base-package="com.application.core"/>
...
<aop:aspectj-autoproxy />
现在所有这些都不起作用了。我的意思是在我的API调用/login
时,所需的通知没有执行。
3条答案
按热度按时间6rvt4ljy1#
当在Spring中的bean上使用AOP时,它只适用于相同应用程序上下文中的bean。
在一个典型的web应用程序中,你会有一个
ContextLoaderListener
和一个DispatcherServlet
,它们都创建了一个ApplicationContext
。ContextLoaderListener
创建了所谓的根应用程序上下文,DispatcherServlet
创建了一个与根上下文相关的子上下文。来自根的AOP配置不会影响子上下文中的bean,而子上下文中的AOP配置也不会影响根上下文中的bean。
现在您已经在根上下文中配置了方面和
<aop:aspectj-autoproxy />
,并将其排除在外,以便为子上下文中的bean工作。显然,这是行不通的。将该配置移动(或复制)到子上下文中。另一件事是你将需要基于类的代理,因为你没有接口,所以你可能还想添加
proxy-target-class="true"
到<aop:aspectj-autoproxy />
元素。tcomlyy62#
看起来还可以,但你应该这样写:
因为有了这个最终的配置,你就可以在springautoproxy基础设施上说出bean在自动代理过程中考虑了什么。听到的关键点是,如果你想使用方面来记录方法调用,它是好的,但如果你想使用方面来记录http调用,它将不起作用,在这种情况下,使用拦截器可能是一个很好的选择。
您可以使用您的org.springframework.web.servlet.HandlerInterceptor或org.springframework.web.context.request.WebRequestInterceptor实现
然后在org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter中注册它,如下所示:
在java配置中或
在您的xml配置文件中使用mvc名称空间
希望这能帮到你
bxfogqkk3#
在我的例子中,@Cacheable禁用了我的AOP注解断点,只需将@Cacheable放在我的AOP注解后面。