0

我的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>

有 2 个 Aspect Java 类,LogControllerAspect(用于记录对 Spring 控制器的所有调用)和 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 方法正在执行两次)。我可以理解该方面被代理两次,但不知道如何避免这种情况。帮助表示赞赏。

4

1 回答 1

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>
于 2013-09-11T07:20:48.217 回答