dubbo服务消费方注入@Reference失败

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo服务消费方注入@Reference失败相关的知识,希望对你有一定的参考价值。

参考技术A Injection of @org.apache.dubbo.config.annotation.Reference dependencies is failed;

No provider available for the service XXXService

出现这个错误的原因有很多,本篇记录自己遇到的坑,其他原因可自行百度,一大堆儿。。。

进入zookeeper客户端查看提供者接口信息

发现服务提供者注册的ip地址与本机配置的ip不一致,使用了本机的虚拟网卡的ip。

通过 ping 命令 192.168.0.102 发现目标ip不可达。

1.查看本机的ip地址  ifconfig命令

2.修改dubbo的配置,将协议的host修改为本机正常可达的ip 如:dubbo.protocol.host=192.168.0.100.

到此如果你的ip是正常可达的基本服务消费方就能正常启动了,并且可调用接口中的方法。

dubbo起停之服务消费

ReferenceAnnotationBeanPostProcessor继承了AnnotationInjectedBeanPostProcessors其实现了InstantiationAwareBeanPostProcessorAdapter接口postProcessPropertyValues方法中,扫描带@Reference注解的成员 注入ReferenceBean对象:

@Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException 

        InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
        try 
            metadata.inject(bean, beanName, pvs);
         catch (BeanCreationException ex) 
            throw ex;
         catch (Throwable ex) 
            throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getName()
                    + " dependencies is failed", ex);
        
        return pvs;

findInjectionMetadata会找出所有@Reference的字段和方法并封装成元数据,metadata.inject方法进去,会调用injectElement的inject方法,进而调用AnnotatedFieldElement的inject方法:

 public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement 

        private final Field field;

        private final A annotation;

        private volatile Object bean;

        protected AnnotatedFieldElement(Field field, A annotation) 
            super(field, null);
            this.field = field;
            this.annotation = annotation;
        

        @Override
        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable 

            Class<?> injectedType = field.getType();

            Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);

            ReflectionUtils.makeAccessible(field);

            field.set(bean, injectedObject);

        

    

 

 protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception 

        String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement);

        Object injectedObject = injectedObjectsCache.get(cacheKey);

        if (injectedObject == null) 
            injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement);
            // Customized inject-object if necessary
            injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
        

        return injectedObject;

    

其中doGetInjectedBean被ReferenceAnnotationBeanPostProcessor重写:

 @Override
    protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception 

        String referencedBeanName = buildReferencedBeanName(reference, injectedType);

        ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader());

        cacheInjectedReferenceBean(referenceBean, injectedElement);

        Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType);

        return proxy;
    

可以看到这里构造了一个referenceBean并返回了一个代理,真正注入的其实是这个代理

以上是关于dubbo服务消费方注入@Reference失败的主要内容,如果未能解决你的问题,请参考以下文章

dubbo学习 springboot整合dubbo mybatis mysql

dubbo起停之服务消费

解决dubbo的服务发布注解@service不能和事务注解不能共用的方案

Dubbo

分布式RPC服务调用框架选型:使用Dubbo实现分布式服务调用

分布式RPC服务调用框架选型:使用Dubbo实现分布式服务调用