Search code examples
springaopspring-aopspring-annotations

AOP: error at ::0 inconsistent binding applying aop on two different methods


I am trying to apply a @before aspect on two different methods in two different paths

class Service1{
    public Object applyX(X x){
     //code
    }
}

class Service2{
    public OtherObject applyY(Y y){
     //code
    }
}

and I have my aspect class:

@Aspect
@Component
public class MyProcessor {

    @Before("execution(* com.a.b.c.Service1.applyX"
            + " (com.xp.X)) "
            + "&& args(engineEvaluationRequest) || "
            + "execution(* com.a.b.d.Service2.applyY"
            + " (com.yp.Y))"
            + "&& args(y)")
    public void process(X x ,Y y){
        //code
    }
}

I am getting an error org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectMapperConfigurer' defined in class path resource [springfox/documentation/spring/web/SpringfoxWebMvcConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 inconsistent binding

and I don't understand what went wrong. can I get help? Thanks!


Solution

  • The error message inconsistent binding already says it: Your variable binding with args() is inconsistent insofar as it is ambiguous due to the || (logical or) operator. Either X is found and can be bound or Y, but the other one would be undefined. You might have assumed that if a variable is not bound it defaults to null, but this assumption is wrong. AspectJ does not work like that. Your pointcut must bind variables unambiguously to the corresponding advice parameters.

    Edit: Because || is a logical OR and thus non-exclusive (unlike XOR), it might even happen that two OR branches match at the same time. Then which matching argument or annotation should be bound? This really is ambiguous.

    So how can you fix it? Just use two pointcut/advice pairs instead of just one. If the advice is complex and contains a lot of code you can still factor out that code into a helper method taking a JoinPoint parameter or so.