Dubbo:@DubboService和@Service、@DubboReference和@Reference的区别和关系

本文介绍了Dubbo中@Service和@Reference注解的历史演变过程,包括从Alibaba时期到Apache时期的变化,以及新注解@DubboService和@DubboReference的引入。详细解释了各个版本之间的区别和改进。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.不同时间的三组注解

在旧版本中,Dubbo使用自己的@Service、@Referenc注解来标注服务与引用。
或许是想与spring等框架的注解区分开,在2.7.7版本后,源码中的@Service、@Referenc被打上了@Deprecated注解,它们被使用的地方都被拦腰打上了横线,表示不建议使用。
在这里插入图片描述
定位到它们所在路径,发现总共有三种相似的注解

在这里插入图片描述
其实它们是Dubbo的三个不同时期的产物,它们的全路径名称如下

// 2.7.x 之前,Alibaba时期
com.alibaba.dubbo.config.annotation.Reference
com.alibaba.dubbo.config.annotation.Service

// 2.7.0之后,Apache时期
org.apache.dubbo.config.annotation.Reference
org.apache.dubbo.config.annotation.Service

// 2.7.7之后
org.apache.dubbo.config.annotation.DubboReference
org.apache.dubbo.config.annotation.DubboService

2.注解的升级

2.1 @Reference

@Reference 相关注解用来引用服务

2.1.1 Alibaba @Reference -> Apache@Reference

2.1.1.1 注解升级

新增注解,路径从com.alibaba变成org.apache,旧注解打上@Deprecated

2.1.1.2 属性增加

2.7.0的Apache版本,比Alibaba的@Reference注解多了protocol、tags、methods、id五个属性,这次升级后,开发者可以做通过protocol指定协议等操作。
在这里插入图片描述

2.1.2 @Reference -> @DubboReference

2.1.2.1 注解升级

2.2.7版本,主要是新注解名称加上Dubbo前缀,显得更直观,旧注解打上@Deprecated
在这里插入图片描述

2.1.2.2 属性增加

同时增加了merger、services属性
在这里插入图片描述

2.2 @Service

@Service 相关注解用来暴露服务

2.2.1 Alibaba @Service -> Apache @Service

2.2.1.1 注解升级

新增注解,路径从com.alibaba变成org.apache,旧注解打上@Deprecated

2.2.1.2 属性修改与增加

2.7.0的Apache版本,
将export、register的默认值从false改为true,
将回调callbacks默认值从空改为1,
将重试次数retries默认值从空改为2
将负载均衡loadbalance默认值从空改为rodom随机
增加了methods、id两个属性
在这里插入图片描述

2.2.2 @Service -> @DubboService

2.2.1.1 注解升级

2.2.7版本,主要是新注解名称加上Dubbo前缀,显得更直观,旧注解打上@Deprecated,属性一点没改,改名的目的很单纯

3.注解在源码中的整合

首先不用多想,dubbo应该支持这三种注解,在老项目升级后也应该兼容老注解,那到底是不是这样,有两种验证方式:源码分析或使用新注解验证实际效果

3.1 源码解析

3.1.1 @Reference家族

查看@DubboReference被使用的地方,除了测试类,只在ReferenceAnnotationBeanPostProcessor中出现,可以看出,此@Reference家族的三个注解都在ReferenceAnnotationBeanPostProcessor的构造方法中,被传入此类继承的AbstractAnnotationBeanPostProcessor构造方法中,所以这三个注解是被一视同仁的,在Spring项目中,不论使用三个之中哪种注解,都归ReferenceAnnotationBeanPostProcessor管,都会被一视同仁。
在这里插入图片描述

	//ReferenceAnnotationBeanPostProcessor:
	/**
     * {@link com.alibaba.dubbo.config.annotation.Reference @com.alibaba.dubbo.config.annotation.Reference} has been supported since 2.7.3
     * <p>
     * {@link DubboReference @DubboReference} has been supported since 2.7.7
     */
    public ReferenceAnnotationBeanPostProcessor() {
    	//直接传入父构造器
        super(DubboReference.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
    }
    
    //AbstractAnnotationBeanPostProcessor:
	/**
     * @param annotationTypes the multiple types of {@link Annotation annotations}
     */
    public AbstractAnnotationBeanPostProcessor(Class<? extends Annotation>... annotationTypes) {
        Assert.notEmpty(annotationTypes, "The argument of annotations' types must not empty");
        //三个注解都放在annotationTypes中
        this.annotationTypes = annotationTypes;
    }

	//annotationTypes三种类型再其他地方被如下逻辑挨个被使用
	for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {

                    AnnotationAttributes attributes = getAnnotationAttributes(bridgedMethod, annotationType, getEnvironment(), true, true);
    // ******
    }

ReferenceAnnotationBeanPostProcessor就不展开了,说跑偏了。
在这里插入图片描述

3.1.2 @Service家族

@Service家族分别在ServiceAnnotationResolver和ServiceClassPostProcessor中被使用,三者被一视同仁,查看源码的逻辑参考上一个@Reference家族的讲解

public class ServiceAnnotationResolver {

    /**
     * The annotation {@link Class classes} of Dubbo Service (read-only)
     *
     * @since 2.7.9
     */
    public static List<Class<? extends Annotation>> SERVICE_ANNOTATION_CLASSES = unmodifiableList(asList(DubboService.class, Service.class, com.alibaba.dubbo.config.annotation.Service.class));
    // ******
}
public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
        ResourceLoaderAware, BeanClassLoaderAware {

    private final static List<Class<? extends Annotation>> serviceAnnotationTypes = asList(
            // @since 2.7.7 Add the @DubboService , the issue : https://github.com/apache/dubbo/issues/6007
            DubboService.class,
            // @since 2.7.0 the substitute @com.alibaba.dubbo.config.annotation.Service
            Service.class,
            // @since 2.7.3 Add the compatibility for legacy Dubbo's @Service , the issue : https://github.com/apache/dubbo/issues/4330
            com.alibaba.dubbo.config.annotation.Service.class
    );
    //******
}

3.2 使用方式

源码自带使用方式

3.2.1 @DubboReference 引用服务

import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.demo.DemoService;

import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

@Component("demoServiceComponent")
public class DemoServiceComponent implements DemoService {
    @DubboReference
    private DemoService demoService;

    @Override
    public String sayHello(String name) {
        return demoService.sayHello(name);
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        return null;
    }
}

3.2.2 @DubboService 暴露服务

import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.demo.DemoService;
import org.apache.dubbo.rpc.RpcContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

@DubboService
public class DemoServiceImpl implements DemoService {
    private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public String sayHello(String name) {
        logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        return null;
    }
}

4.总结

总之来说,@DubboService与@Service、@DubboReference与@Referenc的关系就是更新换代,在使用方式和功能上基本一样,最新的注解是加Dubbo前缀的,使用起来更直观一些

<think>嗯,用户想了解Dubbo中的@Reference注解。好的,首先我得回忆一下Dubbo的基本知识。Dubbo是一个高性能的Java RPC框架,主要用于分布式服务的调用。@Reference应该是用来引用远程服务的注解,类似于Spring中的@Autowired,但用于Dubbo的服务消费者。 用户可能是在使用Dubbo时遇到了服务注入的问题,或者想了解如何正确使用这个注解。需要详细说明@Reference的作用、使用场景以及配置参数。可能还需要提到版本兼容性,比如在Dubbo的不同版本中,这个注解可能有变化,特别是从Dubbo 2.x到3.x的变化。 记得用户提到系统级指令,要确保所有的数学公式代码都用正确的格式。但这里主要是关于Dubbo的注解,可能不需要数学公式,但代码示例可能需要用反引号或者代码块。不过用户要求的是中文回答,结构要清晰,分步骤说明。 需要解释@Reference的基本用法,比如在Spring Boot中如何通过注解注入服务,可能还要提到属性配置,比如version、timeout、loadbalance等参数。此外,需要注意Dubbo的配置方式,比如XML配置注解配置的区别,以及@Reference在注解驱动中的使用。 可能还需要提到一些常见问题,比如空指针异常,原因可能是注解没有正确生效,或者服务未注册到注册中心。这时候需要检查包扫描是否正确,或者是否使用了正确的代理方式。 另外,用户可能想知道@Reference@DubboReference区别,特别是在Dubbo新版本中的变化。比如,Dubbo 3.x推荐使用@DubboReference,而旧版使用@Reference,但具体细节需要准确回忆或确认。 还要考虑依赖注入的上下文,比如在Spring环境中,Dubbo如何Spring集成,是否需要开启注解驱动,或者配置包路径扫描。这些都是使用@Reference时可能需要注意的点。 最后,总结一下@Reference的关键点,确保用户能够理解其作用,并正确应用在实际项目中。可能还需要给出一个简单的代码示例,展示如何使用@Reference注入服务并进行调用。</think>在Dubbo框架中,`@Reference` 是服务消费者端用于**注入远程服务**的核心注解。以下是分层解析: --- ### 一、基本作用 1. **服务引用** 用于建立Dubbo服务提供者的代理连接,实现类似本地接口调用的远程RPC调用 ```java @Service public class OrderServiceImpl implements OrderService { @Reference private UserService userService; // 注入远程服务 } ``` 2. **核心特性** - 支持接口级代理(默认JDK动态代理) - 自动完成服务发现、负载均衡、集群容错等流程 - 支持方法级参数配置覆盖 --- ### 二、核心配置参数 通过注解属性实现精细化控制: ```java @Reference( version = "2.0.0", // 服务版本 timeout = 3000, // 调用超时(ms) loadbalance = "random", // 负载策略 cluster = "failfast", // 集群容错模式 check = false, // 启动时是否检查提供者 retries = 2 // 失败重试次数 ) private PaymentService paymentService; ``` --- ### 三、工作原理 1. **代理生成阶段** - 在Spring容器初始化时,通过`ReferenceAnnotationBeanPostProcessor`处理注解 - 创建Invoker代理对象并注入到目标字段 2. **调用过程** $$ 调用链路 = 本地代理 \rightarrow 过滤器链 \rightarrow 路由选择 \rightarrow 负载均衡 \rightarrow 网络传输 $$ --- ### 四、版本演进注意 | Dubbo版本 | 注解变化 | |---------|---------| | ≤2.7.x | `@Reference`(来自`com.alibaba.dubbo`) | | ≥3.x | 推荐使用`@DubboReference`(新特性支持更好) | --- ### 五、常见问题排查 1. **空指针异常** - 检查包扫描配置:确保`@DubboComponentScan`包含服务接口所在包 - 验证注册中心是否正常显示服务提供者 2. **版本不匹配** ```java // 提供者声明 @Service(version = "2.0.0") public class UserServiceImpl implements UserService {...} // 消费者需对应 @Reference(version = "2.0.0") ``` --- ### 六、最佳实践建议 1. **明确接口版本** 生产环境必须指定`version`属性,避免灰度发布时出现意外调用 2. **合理设置超时** 根据服务SLA配置: $$ 超时时间 ≥ 平均响应时间 × 3 $$ 3. **启用异步调用** ```java @Reference(async = true) private AsyncService asyncService; ``` 如需更深入的实现原理分析(如服务目录更新机制、动态代理生成细节等),可以进一步说明需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Archie_java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值