【问题标题】:Spring AOP Advice is being executed twiceSpring AOP Advice 被执行两次
【发布时间】:2015-01-07 08:48:45
【问题描述】:

我正在使用 Spring AOP 创建一个方面。我定义的 Aspect 被执行了两次。我似乎无法弄清楚为什么。我很感激任何人对此问题的任何意见。

谢谢!

// 弹簧配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
    default-autowire="no"
    default-lazy-init="true">

    <bean id="loggingAdvice" class="com.xyz.aop.LoggingAdvice" />
    <aop:config>
        <aop:aspect id="loggingAspect" ref="loggingAdvice">
            <aop:pointcut id="loggingPointcut"
                expression="execution(* com.xyz.FooServiceImpl.foo(..))"/>
                <aop:around pointcut-ref="loggingPointcut" method="log" />
        </aop:aspect>
    </aop:config>

    <context:component-scan base-package="com.xyz.controllers" />

</beans>

// 建议

package com.xyz.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggingAdvice {
    public Object log(final ProceedingJoinPoint pjp) throws Throwable {
        log.info("Started!");
        try {
            return pjp.proceed();
        } finally {
            log.info("Ended!");
        }
    }
}

// 建议方法

package com.xyz;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FooServiceImpl implements FooService {
    private static final Log log = LogFactory.getLog(FooServiceImpl.class);

    @Override
    public void foo()  {
         log.info("Foo!");
        }
    }
}

// 输出

   Started!
   Started!
   Foo!
   Ended!
   Ended!

// 编辑 1:添加了更多弹簧配置信息。根本不使用任何 Spring AOP 注释。我附加了一个调试器,发现方面/日志语句也被执行了两次。所以我怀疑它与两次打印字符串的日志语句有什么关系。

【问题讨论】:

  • 如果它被执行两次,它会被检测/应用两次。确保您没有@Aspect 或其他应用 AOP 的方式。
  • @M.Deinum:您可以将评论移至答案。我认为这是正确的。
  • 您能发布更多配置吗?是你的整个LoggingAdvice 还是缺少一些注释,同样适用于配置我怀疑还有更多...
  • 非常感谢您的回复,M. Deinum。我已经发布了更多的配置。我在任何地方都没有@Aspect 注释。我已经检查过了,我在其他地方没有看到任何其他 Spring AOP 配置。我附加了一个调试器,发现控制流程如下: 1. log.info("Started!"); 2. pjp.proceed(); 3. log.info("开始!"); 4. pjp.proceed(); 5. log.info("Foo!"); 6. log.info("结束!"); 7. log.info("结束!")
  • 问题解决了吗?你能发布你的日志配置吗?

标签: java spring spring-mvc aop spring-aop


【解决方案1】:

嗯,看来这实际上是记录器的问题。我很久以前遇到过同样的问题,发现所有内容都被记录了两次。当我用常规的 sysout 调用替换记录器调用时,一切正常。

【讨论】:

  • 这似乎没有多大意义。
  • 与记录器无关。我用 Sys.out 语句替换了日志语句,发现它们也被执行了两次。我实际上附加了一个调试器并逐步通过程序来验证这一点。
【解决方案2】:

因为&lt;aop:around...> 告诉它在方法之前和之后都可以工作。您可以使用&lt;aop:before...&gt;&lt;aop:after...&gt; 代替只运行一次。

【讨论】:

  • 这说不通,真的。
猜你喜欢
  • 2013-10-23
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多