Java 使用Spring AOP时,在单个连接点上绑定参数的多个环绕通知会导致错误

Java 使用Spring AOP时,在单个连接点上绑定参数的多个环绕通知会导致错误,java,spring,aop,spring-aop,Java,Spring,Aop,Spring Aop,我在一个方法上写了2条注释,并在处理每个注释值时写了2条建议 连接点方法如下所示: @CacheFetch(cacheName = CacheManager.CACHE_DATASOURCE_INFO) @TenantAware(method = OperationMethod.OPERATION, operation = OperationType.GET) public DataSourceInfo fetchDataSource(String sourceId) {...} @Aroun

我在一个方法上写了2条注释,并在处理每个注释值时写了2条建议

连接点方法如下所示:

@CacheFetch(cacheName = CacheManager.CACHE_DATASOURCE_INFO)
@TenantAware(method = OperationMethod.OPERATION, operation = OperationType.GET)
public DataSourceInfo fetchDataSource(String sourceId) {...}
@Around("within(com.xx.yy.zz..*) && @annotation(fetch)")
public Object fetchFromCache(ProceedingJoinPoint pjp, CacheFetch fetch) throws Throwable {...}
@Around("isXXX() && @annotation(tenantAware)")
public Object handleTenantAware(ProceedingJoinPoint pjp, TenantAware tenantAware) throws Throwable {...}
建议1如下:

@CacheFetch(cacheName = CacheManager.CACHE_DATASOURCE_INFO)
@TenantAware(method = OperationMethod.OPERATION, operation = OperationType.GET)
public DataSourceInfo fetchDataSource(String sourceId) {...}
@Around("within(com.xx.yy.zz..*) && @annotation(fetch)")
public Object fetchFromCache(ProceedingJoinPoint pjp, CacheFetch fetch) throws Throwable {...}
@Around("isXXX() && @annotation(tenantAware)")
public Object handleTenantAware(ProceedingJoinPoint pjp, TenantAware tenantAware) throws Throwable {...}
忠告2如下:

@CacheFetch(cacheName = CacheManager.CACHE_DATASOURCE_INFO)
@TenantAware(method = OperationMethod.OPERATION, operation = OperationType.GET)
public DataSourceInfo fetchDataSource(String sourceId) {...}
@Around("within(com.xx.yy.zz..*) && @annotation(fetch)")
public Object fetchFromCache(ProceedingJoinPoint pjp, CacheFetch fetch) throws Throwable {...}
@Around("isXXX() && @annotation(tenantAware)")
public Object handleTenantAware(ProceedingJoinPoint pjp, TenantAware tenantAware) throws Throwable {...}
这两个建议在不同的方面类中,方面类都实现了有序接口。当程序到达fetchDataSource连接点方法时,会发生异常:

java.lang.IllegalStateException: Required to bind 2 arguments, but only bound 1 (JoinPointMatch was NOT bound in invocation)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.argBinding(AbstractAspectJAdvice.java:591)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
如果删除其中一条建议,错误将消失,其余建议将正常工作。我已经搜索了这个问题,大部分结果都来自非常古老的spring版本

我目前的Spring框架和方面版本是4.1.6。我尝试升级到4.1.9和4.3.20,但问题仍然存在


我知道上面的代码应该有效,我自己也没有发现任何错误。我不确定这是一个bug还是其他我不知道的东西。任何帮助都将不胜感激。谢谢。

问题已解决,但仍有问题

我使用的两个方面类的顺序设置为
Ordered.HIGHEST\u priority
Ordered.lower\u priority
。如果我用另一个值替换order值
Ordered.HIGHEST_priority
,错误就会消失。非常奇怪的现象,异常显示与实际原因无关。有人知道实际原因吗?

这首先是由于未加载造成的,它将导致将不会通过Springbean注入参数(对于
CacheFetch

此外,您还可以在中找到:

也有人试图通过使用
PriorityOrdered
来解决这个问题,但似乎还没有进行

因此,对于您的问题,有两种解决方案:

  • 更改
    顺序
    不是
    最高优先级
    ,可能是
    最高优先级+1

  • 通过
    ApplicationContext.getBean手动注入bean


  • 我发现另一种情况可能会使
    Exposeinvocationinterceptor
    中的调用无效,从而导致
    org.springframework.aop.aspectj.aspectjexpressionpointcutා matches(java.lang.reflect.method,java.lang.class)我遇到了这种情况(确切地说,是我在这里试图帮助的一个人这么做的)。您链接到的Spring问题已经结束。我再次对此发表了评论,希望重新打开它。同时,您能否详细说明您的解决方案#2?我需要在哪里注入哪个bean?