【问题标题】:Spring AOP advice is called twiceSpring AOP 建议被调用两次
【发布时间】:2011-12-15 14:23:43
【问题描述】:

我有以下 Spring AOP 建议,但我不知道为什么它被调用了两次:

@Component
@Aspect
public class LoggingAspects {

    Logger logger = LoggerFactory.getLogger(LoggingAspects.class);

    @AfterReturning(pointcut = "execution(public * com.A.B.C.service.impl.*.browse(..))",
            returning = "retVal")
    public Object onBrowse(DomainClass retVal) {
        logger.info("#######################Advice Called: +retVal);
        return null;
    }

}

配置就这么简单:

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

<bean id="loggingCASAspect" class="com.minervanetworks.xtv.stb.service.aspects.LoggingCASAspects"/> 

我也尝试了以下建议,结果相同(调用了两次)。

@AfterReturning(pointcut="@annotation(com.A.B.C.service.impl.LOG)", returning="retVal")
public Object onBrowse(JoinPoint jp, DomainClass retVal) {
    logger.info("#######################Advice called! " + jp.toLongString()
    + " Target: " + jp.getTarget()
    + " Signature: " + jp.getSignature()
    + " Kind: " + jp.getKind()
    + " This: " + jp.getThis()
    + " Source Location: " + jp.getSourceLocation());

    return null;
}

来自上述记录器的调试信息是:

2011-10-26 11:56:01,887 [INFO][com.A.B.C.service.aspects.LoggingAspects] #######################Advice called! execution(public abstract com.A.B.C.domain.DomainClass com.A.B.C.service.ContentManager.browse(java.lang.String,java.lang.String,java.lang.String,java.lang.Boolean)) Target: com.A.B.C.service.impl.ContentManagerImpl@62ad191 Signature: DomainClass com.A.B.C.service.ContentManager.browse(String,String,String,Boolean) Kind: method-execution This: com.A.B.C.service.impl.ContentManagerImpl@62ad191 Source Location: org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@d324de2

以完全相同的值显示两次。

【问题讨论】:

  • 我讨厌问显而易见的问题,但是该方法会被调用两次吗?
  • 这是第一件事,我确实检查过。该方法只被调用一次。抱歉,我错过了在原始问题中提及这一点。

标签: aop spring-aop


【解决方案1】:

1.提示

您使用 JavaConfig 还是 xml? 如果您同时使用两者,则可能是 Spring IoC 容器正在处理 Aspect 两次。

2。提示

我不使用@Component 注释来注释方面,尝试将其删除,可能是因为 Spring 正在处理两次。

【讨论】:

  • 我也有同样的问题。但是,如果我删除 @Component,它会停止记录。以下是课程
  • @Component(或其他 Spring 原型)是组件扫描所必需的。如果您能够通过删除此注释来解决此问题,则必须使用除组件扫描之外的其他接线机制。
  • 另一个提示:如果您的 AOP 类在另一个模块/项目中,您可能希望保留 @Component。它将按预期执行一次。
【解决方案2】:

我发现如果切面被声明为请求范围,那么通知可以被调用两次。在这种情况下,同一个 bean 被注册为具有不同名称的拦截器两次:someAspectscopedTarget.someAspect。我通过将 Aspect 设置为单例解决了这个问题。

版本:Spring Boot 2.0.x

【讨论】:

    【解决方案3】:

    尚未提及,但请注意您的切入点与其他方法调用不匹配。

    例如,在我的例子中,我调用了不同的 Beans : 豆A -> 豆B -> 豆C

    我想给 Bean A 添加一个切面,但是 Bean B 的方法签名也匹配了切入点,在 2 个方法调用中解析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多