dubbo番外篇-bug之【aop失效】
条评论本文浅述:在使用dubbo时,spring aop失效问题。如果你也遇到该问题,先检查是否使用@Reference注入dubbo服务的。
场景还原
版本:我使用的dubbo版本是2.6.
场景:我想消费者在调用我的dubbo接口时,都将自己应用名传过来,方便我鉴权,所以我在我提供的二方包中,提供aop,想通过dubbo的附加参数,将应用名传过来。大致代码如下:
1 | package com.xxxx.service; |
调用方式大致如下:
1 |
|
最后肯定没有如我所愿,要不然也不会有这一篇文章了。现象呢,始终走不到aop中。
原因分析
一切看起来很奇怪,我还特地验证了会不会因为我切入的是interface的问题。我在消费者项目中新建一个接口,然后用aop切人,用@Autowired注入,调用时aop能正常工作。
那么aop切入点是dubbo的接口时,为什么就走不到aop呢?这两个case对于调用者来说,唯一的区别就是一个用@Reference注入,一个用@Autowired注入。正好我也想看一下dubbo的@Reference的工作原理,就趁此机会看一眼。
废话不说,ctrl+shift+f搜索“Reference.class”,我找到了DubboConsumerAutoConfiguration,看到代码如下:
1 | public class DubboConsumerAutoConfiguration extends DubboCommonAutoConfiguration { |
可以看到,Reference是想通过spring注入BeanPostProcessor,在spring bean创建之后、初始化之前,将标注了@Reference注解的字段,为其new一个ReferenceBean,并保存application、registry等参数。而ReferenceBean实现了FactoryBean,则可以通过getObject()返回该字段的对象,当然其中还有缓存啥的,各位可以自己了解。然后拿到这个对象之后,通过反射调用field.set(bean, dubboReference)来注入。
至此,@Reference工作原理到此解释详尽。那么回顾aop。aop是spring提供的功能,再看看@Reference工作原理跟spring有半毛钱关系嘛?是不是完全没有经过spring 的 ioc ,那么spring怎么能给你实现aop的功能呢!!!!
解决方案
注入ioc中的bean
明白了原因了,那么我们就避免使用@Reference,然后用spring 的 @Autowired注入不就行了嘛。于是我用xml+@Autowired进行以下测试
1 | <dubbo:reference interface="com.xxxx.service.XxxxService" id="xxxService" check="false" |
那么这次结果肯定是令我满意的,aop工作的很好,那么我做的是中台应用,要是对方不愿意使用xml+@Autowired注入怎么办呢?
自己解决不了就抛出去
哈哈,在dubbo群里有小伙伴,可能看到聊天记录了,在很久之前我就把它抛给小马哥了。还挺佩服阿里的工作效率的,我当天说完,提完issue,当天就定为新特性,第二天就fix掉了。
issue:https://github.com/apache/dubbo/issues/5446
pr:https://github.com/apache/dubbo/pull/5454
该问题在 2.7.6 中,当作新特性上线,大家也可以升级到这个版本,来解决这一问题。
- 本文链接:https://www.ofcoder.com/2020/01/07/java/dubbo%E7%95%AA%E5%A4%96%E7%AF%87-bug%E4%B9%8B%E3%80%90aop%E5%A4%B1%E6%95%88%E3%80%91/
- 版权声明:Copyright © 并发笔记 - ofcoder.com. Author by far.
分享