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

查看:729
本文介绍了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 Controllers的所有调用)和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天全站免登陆