如何理解@Resource和@Reference的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解@Resource和@Reference的区别相关的知识,希望对你有一定的参考价值。

参考技术A 1,定义:

@Resource:spring的注解,作用:spring中获取已经注入到spring中的Bean

@Reference: dubbo的注解,作用:注入duboo服务的对象

2,遇到问题:

本地配置:

报错:No provider available from registry **** for service ------------

哇,经典报错,一看错误就以为是生产者没有启动喽,去zk上面看dubbo生产者情况,真的没有,问题好像已经找到了,,等等,忽然发现他为什么去的是 registry 1呢,不应该去1和2都找吗? 对了,@Reference 注册dubbo不管是什么方式,无非是registry 和 version等指定,由于我没有指定,那按照spring的理解肯定是走自动装配喽,那我这边配置了两个注册中心,是不是他会智能的都找找呢?(不是的,dubbo生产者如果指定多个registry,然后<dubbo:service/>声明的服务会注册到多个注册中心,<dubbo:reference/>消费端多注册中心时是需要指定去哪个注册中心的)我不想在@Reference后面写一大堆,就想走自动化装配,最后找到可以在registry声明时 default 的属性的,

根据一系列的猜测、我把配置改为了:

自此问题解决了,,,,,

我发现新的问题:使用@Reference来注入dubbo服务,那如果我项目中多个地方想使用,我在多个类中使用@Reference ,岂不是注入多个bean了(这个理解是有问题的,这时未意识到)。这显然是有问题的,因此我想将dubbo服务以单例注入到spring中,换成 spring自己的@Resource标签来获取,因此我将配置改成了一下:

测试一下:确实好使,,自此配置使用方面没什么问题了,符合一个人的正常逻辑了,

但是还有一个问题,就是:

“我发现新的问题:使用@Reference来注入dubbo服务,那如果我项目中多个地方想使用,我在多个类中使用@Reference ,岂不是注入多个bean了 ”  这个问题真的存在吗?

下面来解答这个问题:

spring的配置 使用 xml 或者注解 只是 使用方式的不同,@Reference 和 <dubbo:reference/> 的效果应该是是一样的, spring默认注入Bean,scope应该是singleton ,  那我在多个类中使用@Reference 注入同一个dubbo服务应该是在spring中只存在一个了,,事实上的是的,

多个@Reference 标签 注入配置信息完全相同的 服务 ,是会有服务Bean缓存的,保证只会有一个 服务Bean ,源码如下:  这个方法 generateReferenceBeanCacheKey  是缓存key的获取。。

private ReferenceBean<?> buildReferenceBean(Reference reference, Class<?> referenceClass) throws Exception         // 获取服务引用对象的缓存key        String referenceBeanCacheKey = generateReferenceBeanCacheKey(reference, referenceClass);        // 从缓存map中获取服务引用对象        ReferenceBean<?> referenceBean = referenceBeansCache.get(referenceBeanCacheKey);        if (referenceBean == null)             // 如果引用对象为空,则需要当场创建一个            ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder                    .create(reference, classLoader, applicationContext)                    .interfaceClass(referenceClass);            referenceBean = beanBuilder.build();            //并且放入到缓存map中。            referenceBeansCache.putIfAbsent(referenceBeanCacheKey, referenceBean);                return referenceBean;    private String generateReferenceBeanCacheKey(Reference reference, Class<?> beanClass)         // 获取接口名称        String interfaceName = resolveInterfaceName(reference, beanClass);        // 通过引用的URl+接口名+接口版本号+接口分组,用来做缓存key        String key = reference.url() + "/" + interfaceName +                "/" + reference.version() +                "/" + reference.group();        Environment environment = applicationContext.getEnvironment();        key = environment.resolvePlaceholders(key);        return key;   

自此问题说明完毕。。

问题整理:

1,多注册中心时,spring 自动化装配时,需要自己指定 某一个注册中心 或者 将某个注册中心 default设置为true.

2, @Resource 和 @Reference 都可 注入 dubbo服务但是 概念是不一样的。

3,@Reference 注解可以在多个类中注入 相同服务Bean 不会造成服务Bean 存在多个。。

注:源码参考 文章 https://shared-code.com/article/121

@reference和@resource的区别

参考技术A @reference是dubbo注解,@resource是spring 注解。

@resource作用相当于@Autowired,只不过@Autowired是 byType 自动注入,而@Resource默认 byName 自动注入。

@Reference是dubbo的注解,也是注入,但是一般用来注入分布式的远程服务对象,需要配合dubbo配置使用。

@reference和@resource的区别就是@resource是本地spring容器,@reference是把远程服务对象当做spring容器中的对象一样注入。

以上是关于如何理解@Resource和@Reference的区别的主要内容,如果未能解决你的问题,请参考以下文章

@reference和@resource的区别

How do I duplicate a resource reference in code behind in WPF?

解决问题 inner element must either be a resource reference or empty.

【dubbo源码】13. 服务消费方之@Reference依赖注入原理

spring中@Resource和@Autowired理解

SLURM RPC Reference