Spring AOP advice is called twice
Asked Answered
H

5

7

I have the following Spring AOP advice and I can't find out why it is called twice:

@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;
    }

}

The configuration is as simple as that:

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

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

I have also tried the following advice with the same result (called twice).

@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;
}

The debug info from the above logger is:

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

It is displayed twice with exactly the same values.

Holcman answered 26/10, 2011 at 9:31 Comment(2)
I hate asking the obvious, but is the method being called twice?Gundry
That was the first thing, I did check. The method is called only once. Sorry that I missed to mention that in the original question.Holcman
C
20

1. hint

Do you use JavaConfig or xml? If you're using both, it could be that the Aspect is being processed two times by the Spring IoC container.

2. hint

I don't annotate aspects with @Component annoation, try to remove it, maybe because of that is being processed twice by Spring.

Cannoneer answered 27/10, 2011 at 10:17 Comment(3)
I exactly have same issue. However if I remove @Component, it stops logging. Following is the classBurmaburman
@Component (or another Spring stereotype) is required for component scanning. If you were able to fix the issue by removing this annotation some other wiring mechanism than component scanning must be effective.Patrimony
Another hint: You would want to keep @Component if your AOP class was in another moduke/project. It will execute once as expected.Balmung
H
4

I found that the advice can be called twice if the aspect is declared as request-scoped. In this case the same bean is registered twice as an interceptor with different names: someAspect and scopedTarget.someAspect. I solved this issue by making the Aspect a singleton.

Version: Spring Boot 2.0.x

Hiragana answered 16/10, 2018 at 12:11 Comment(0)
B
1

It haven't been mentioned, but take care that your pointcut is not matching other method calls.

For example in my case, I was calling different Beans : Bean A -> Bean B -> Bean C

I wanted to add an aspect to Bean A, but Bean B method signature was also matching the poincut, resolving in 2 methods calls.

Bonheur answered 29/11, 2021 at 8:39 Comment(0)
O
0

I had the same issue caused by the annotation below.

@Aspect
@Service
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)

The solution was to remove the Scope request annotation.

@Aspect
@Service
Overestimate answered 29/4, 2022 at 11:16 Comment(0)
E
0

for me,remove the @Component is working

--before--

@Aspect
@Component
class Aop {
@Around("@annotation(*.*.*.*)")
fun around(pjp: ProceedingJoinPoint):Any?{
    do  something
  }
}

--after--

@Aspect    
class Aop {
@Around("@annotation(*.*.*.*)")
fun around(pjp: ProceedingJoinPoint):Any?{
    do  something
  }
}
Emissive answered 10/8, 2022 at 5:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.