Spring AOP在单一连接点(JoinPoint)上使用多个带绑定的Around切面方法(advice)时报错
在一个方法上使用2个注解,并用两个不同的切面分别去处理这两个注解中的值,连接点方法如下所示:
@CacheFetch(cacheName = CacheManager.CACHE_DATASOURCE_INFO)
@TenantAware(method = OperationMethod.OPERATION, operation = OperationType.GET)
public DataSourceInfo fetchDataSource(String sourceId) {...}
切面方法1:
@Around("within(com.xx.yy.zz..*) && @annotation(fetch)")
public Object fetchFromCache(ProceedingJoinPoint pjp, CacheFetch fetch) throws Throwable {...}
切面方法2:
@Around("isXXX() && @annotation(tenantAware)")
public Object handleTenantAware(ProceedingJoinPoint pjp, TenantAware tenantAware) throws Throwable {...}
两个切面方法写在了2个不同的Aspect类中,并实现了Ordered接口。当执行到切入点方法时,报出以下错误:
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还是用法问题。希望有人能帮忙,多谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
挖,跟随源码很容易可以发现,在两个指定了不同@Order后,代理的顺序被明显的区分出来。而代理后的方法没有注解,导致第二个切面参数个数不匹配。
两个改进方案:(前提是一定需要指定切面顺序,且想使用注解切面)
你的问题在于利用了注解的形式
@annotation(tenantAware)")
去获取参数,在只切一次的情况下没有问题,但是切面嵌套就不行了,你可以利用传统的方式去获取这个tenantAware
就行了。如果是实现了Ordered接口,它默认值如下。
如果是两个Ordered的话,拦截器估计不能判断谁优先, @Order 时可指定一个int型的value属性,该属性值越小,则优先级越高。
例如:
你试试看