Aspectj不会在Spring框架中捕获所有事件吗?

时间:2020-03-05 18:46:28  来源:igfitidea点击:

我的项目基于spring框架2.5.4. 我尝试为某些控制器添加方面(我使用Aspectj 1.5.3)。

我已经在application-servlet.xml中启用了自动代理,只是将这些行粘贴到xml文件的末尾:

<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />

创建的方面:

package com.example.bg.web.utils;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AuditLogProcessor
{
    private final static Logger log = Logger.getLogger(AuditLogProcessor.class);

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterHandleRequest() {
        log.info("test111");
    }

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterRebuildThumbnail() {
        log.info("test222");
    }
}

我的控制器:

class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController

当我在方面顾问中设置制动点并调用控制器时,我仅捕获afterHandleRequest()而不捕获afterRebildThumbnail()
我做错什么了?

笔记

我代表无法访问SO beta的朋友问这个问题,我不知道它的全部含义。

编辑

确实有一些拼写错误,谢谢Cheekysoft。但是问题仍然存在。

解决方案

回答

AspectJ在Spring Web MVC框架中不能很好地与类配合使用。阅读页面右侧"打开扩展..."框的底部

相反,请看一下HandlerInterceptor接口。

从那时起,新的Spring MVC注释也可以正常工作,因为Controller类都是POJO,但是我自己还没有尝试过。

回答

这像拼写一样简单吗?还是这个问题只是错别字?
有时我们会写rebuildThumbnail,有时会写rebildThumbnail

我们试图用建议覆盖的方法不是MVC框架中的最终方法,因此虽然bpapas答案很有用,但我的理解是,在这种情况下这不是问题。但是,请确保rebuildThumbnail控制器操作不是最终的

@bpapas:如果我错了,请纠正我。程序员自己的控制器动作就是他要覆盖的动作。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。查看MultiActionController源代码(及其父级),堆栈中唯一可能最终确定的方法是MultiActionController.invokeNamedMethod,尽管我不确定100%是否当时在堆栈中。在堆栈的较高位置使用终结方法会导致在将AOP建议添加到较低位置的方法时引起问题吗?

回答

基本设置看起来还可以。

通过不定义就地切入点并仅指定应应用事后通知的方法,可以稍微简化语法。 (方法的命名切入点将自动为我们创建。)

例如

@After( "com.example.bg.web.controllers.assets.AssetAddController.handleRequest()" )
public void afterHandleRequest() {
    log.info( "test111" );
}

@After( "com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail()" )   
public void afterRebuildThumbnail() {
    log.info( "test222" );
}

只要rebuildThumbnail方法不是最终方法,并且方法名称和类正确。我不明白为什么这行不通。

参见http://static.springframework.org/spring/docs/2.0.x/reference/aop.html

回答

因为使用的是Spring的AOP代理,所以不会遇到断点。有关AOP代理有何特殊之处的说明,请参见理解aop代理。

基本上,MVC框架将在控制器的代理上调用handleRequest方法(例如,我们用作基类的MultiActionController实现),然后此方法将对其rebuildThumbnail方法进行"内部"调用,但是不会通过代理,因此不会涉及任何方面。 (这与最终方法无关。)

要实现所需的功能,请通过加载时间编织(Spring很好地支持)来研究使用"真实" AOP。