Spring AOP 控制器执行两次 [英] Spring AOP Controller Executing twice

查看:63
本文介绍了Spring AOP 控制器执行两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的applicationContext如下

My applicationContext is as follows

<?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 的所有调用).

Have 2 Aspect Java classes, LogControllerAspect (for logging all the calls to Spring Controllers) and LogDAOAspect (for logging all the calls to 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 方法执行了两次).我可以理解该方面被代理两次,但我不确定如何避免这种情况.感谢帮助.

LogDAOAspect is fine, but LogControllerAspect is logging twice (logAround method is executing twice) when I request some page. I can understand that that aspect is getting proxied twice, but am not sure how to avoid this. Help appreciated.

推荐答案

这是一个愚蠢的错误.这甚至不是与弹簧相关的问题!我有如下设置 log4j !!!???!!!

It was a silly mistake. It was not even a spring related issue! I had setup log4j as follows !!!???!!!

<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.你的问题确实帮助我仔细观察了该方法内部到底发生了什么.

Thank you @erencan. You question really helped me look closely what is really happening inside that method.

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

Changed is at follows, and it work fine. Should log4j to this question's tags!

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

这篇关于Spring AOP 控制器执行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆