dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解

一、现象说明

  • 在单使用spring的时候,controller 会在 运行期 根据 泛型依赖注入 相应的 service;
  • 使用dubbo拆分时,controller 层只会注入BaseService的实体,而本案例BaseService为abstract类型,dubbo provider端 初始化时并不会在zookeeper中注册,以至于 consumer端 生成不了 相应的proxyObject。

二、案例代码结构

1.service 层, 在provider端

5cda644625a9846ce638a7aac7da82fe173.jpg

865d9fcdc27041ea494d9e720fc22868827.jpg

2.controller 层,在consumer 端

0e901b55e3bd6c3ed942ac37ff8d4c3ff6b.jpg

三、断点跟进

1.dubbo初始化  会将 对象放入 ReferenceAnnotationBeanPostProcessor类中的 HashMap类型的 injectionMetadataCache缓存起来

ReferenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition() 
--> 
findReferenceMetadata(){ 
    ...
    metadata = buildReferenceMetadata(clazz); // 构建元数据
    this.injectionMetadataCache.put(cacheKey, metadata); // 放入injectionMetadataCache对象中
    ..
}
-->
  • 停在要找的userController ,看一下 metadata 怎么生成的?

08d8846dc55f020b16998b1e22430c65099.jpg

//跟进buildReferenceMetadata方法
private ReferenceInjectionMetadata buildReferenceMetadata(final Class<?> beanClass) {
    // 利用spring的RefelectUtils获取Field,Method
    Collection<ReferenceFieldElement> fieldElements = findFieldReferenceMetadata(beanClass);
    Collection<ReferenceMethodElement> methodElements = findMethodReferenceMetadata(beanClass);
    return new ReferenceInjectionMetadata(beanClass, fieldElements, methodElements);

}
-->跟进 findFieldReferenceMetadata() 方法
  • 看一下field 是下面个东西

15b92bb1fc546977b704263679034b6584a.jpg

2.dubbo被调用,也就是userController 实例化 执行 populateBean 给属性 baseService 赋值的时候。

  • 会有很多beanPostProcessor 进行前置处理
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
       if (bp instanceof InstantiationAwareBeanPostProcessor) {
          InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
          PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
             if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
             }
            // 找到ReferenceAnnotationBeanPostProcessor 跟进
             pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
             if (pvsToUse == null) {
                return;
             }
          }
          pvs = pvsToUse;
       }
    }
  • 找到ReferenceAnnotationBeanPostProcessor 跟进 postProcessPropertyValues
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
    
        //因为 InjectionMetadata 被初始化过了,所以是直接从缓存 injectionMetadataCache 对象中取到
        InjectionMetadata metadata = findReferenceMetadata(beanName, bean.getClass(), pvs);
        try {
        // 关键方法,会生成baseService的代理对象然后注入到bean里,有兴趣的可以继续跟进一下。
            metadata.inject(bean, beanName, pvs);
        } catch (BeanCreationException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of @Reference dependencies failed", ex);
        }
        return pvs;
    }
  • 最后会生成这样的代理对象,并不是想要的userService的代理对象。f52ccf957fa53e454aacb85bb814401f0bb.jpg

使用不深,请问大神们, 想要泛型依赖注入,怎么解?

转载于:https://my.oschina.net/u/3293842/blog/3036344

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值