大家春节假期好哦,我是内个内个内个内个内个内~~~~
在旧版本中,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
@Reference 相关注解用来引用服务
新增注解,路径从com.alibaba变成org.apache,旧注解打上@Deprecated
2.7.0的Apache版本,比Alibaba的@Reference注解多了protocol、tags、methods、id五个属性,这次升级后,开发者可以做通过protocol指定协议等操作。
2.2.7版本,主要是新注解名称加上Dubbo前缀,显得更直观,旧注解打上@Deprecated
@Service 相关注解用来暴露服务
新增注解,路径从com.alibaba变成org.apache,旧注解打上@Deprecated
2.7.0的Apache版本,
将export、register的默认值从false改为true,
将回调callbacks默认值从空改为1,
将重试次数retries默认值从空改为2
将负载均衡loadbalance默认值从空改为rodom随机
增加了methods、id两个属性
2.2.7版本,主要是新注解名称加上Dubbo前缀,显得更直观,旧注解打上@Deprecated,属性一点没改,改名的目的很单纯
首先不用多想,dubbo应该支持这三种注解,在老项目升级后也应该兼容老注解,那到底是不是这样,有两种验证方式:源码分析或使用新注解验证实际效果
查看@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
*
* {@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就不展开了,说跑偏了。
@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
);
//******
}
源码自带使用方式
package org.apache.dubbo.demo.consumer.comp;
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;
}
}
package org.apache.dubbo.demo.provider;
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;
}
}
总之来说,@DubboService与@Service、@DubboReference与@Referenc的关系就是更新换代,在使用方式和功能上基本一样,最新的注解是加Dubbo前缀的,使用起来更直观一些