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

一、现象说明

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

二、案例代码结构

1.service 层, 在provider端

dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第1张图片

dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第2张图片

2.controller 层,在consumer 端

dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第3张图片

三、断点跟进

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

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

dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第4张图片

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

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

dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第5张图片

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的代理对象。dubbo-2.6.2 的 consumer 端不支持泛型依赖注入?喜欢泛型编程的,求解_第6张图片

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

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

你可能感兴趣的:(java,大数据)