Spring AOP控制器执行两次

时间:2013-09-11 02:00:28

标签: spring log4j aop aspectj spring-aop

我的applicationContext如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="..">
    <mvc:annotation-driven/>
    <task:annotation-driven/>
    <mvc:resources mapping="/resources/**" location="/resources/"/>
    <aop:aspectj-autoproxy />
    <context:component-scan base-package="com.abc">
        <context:include-filter type="aspectj"  expression="com.abc.aspects.LogControllerAspect"/>
    </context:component-scan>
    <context:annotation-config />
</beans>

有两个Aspect Java类,LogControllerAspect(用于记录对Spring Controllers的所有调用)和LogDAOAspect(用于记录对DB的所有调用)。

@Aspect
@Service
public class LogDAOAspect {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("execution(* com.*.*DAOImpl.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodId = joinPoint.getTarget().getClass().getSimpleName()+" : "+joinPoint.getSignature().getName() + " : " + ((joinPoint.getArgs()==null||joinPoint.getArgs().length<1)?"":(Arrays.toString(joinPoint.getArgs())));
        Object returnVal = null;
        StopWatch sw = new StopWatch(methodId);
        try {
            sw.start();
            returnVal= joinPoint.proceed(joinPoint.getArgs());
            sw.stop();
        } catch (Throwable e) {
            logger.error(methodId+"\n"+e);
            throw e;
        }
        logger.debug(methodId + ":" +sw.getTotalTimeMillis());
        return returnVal;
    }
}


@Aspect
public class LogControllerAspect {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("execution(* com.*.*Controller.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodId = joinPoint.getTarget().getClass().getSimpleName()+" : "+joinPoint.getSignature().getName() + " : " + ((joinPoint.getArgs()==null||joinPoint.getArgs().length<1)?"":(Arrays.toString(joinPoint.getArgs())));
        Object returnVal = null;
        StopWatch sw = new StopWatch(methodId);
        try {
            sw.start();
            returnVal= joinPoint.proceed(joinPoint.getArgs());
            sw.stop();
        } catch (Throwable e) {
            logger.error(methodId+"\n"+e);
            throw e;
        }
        logger.debug(methodId + ":" +sw.getTotalTimeMillis());
        return returnVal;
    }
}

LogDAOAspect很好,但是当我请求某个页面时,LogControllerAspect正在记录两次(logAround方法正在执行两次)。我可以理解,这方面已经被代理了两次,但我不确定如何避免这种情况。帮助赞赏。

1 个答案:

答案 0 :(得分:0)

这是一个愚蠢的错误。它甚至不是春天相关的问题! 我安装log4j如下!!! ??? !!!

<appender name="AppAppender" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="DatePattern" value=".yyyy-MM-dd.HH"/>
    <param name="File" value="logs/logfile.log"/>
    <param name="Append" value="true"/>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%-5p : %d{ISO8601} : %m%n"/>
    </layout>
</appender>

<logger name="com.abc.aspects.LogControllerAspect">
    <priority value="debug"></priority>
    <appender-ref ref="AppAppender"/>
</logger>

<root>
    <priority value="error" />
    <appender-ref ref="AppAppender" />
</root>

谢谢@erencan。你的问题确实帮助我仔细研究了该方法中真正发生的事情。

更改如下,并且工作正常。应该log4j到这个问题的标签!

<logger name="com.abc.aspects.LogControllerAspect" additivity="false">
    <priority value="debug"></priority>
    <appender-ref ref="AppAppender"/>
</logger>