当前位置:   article > 正文

Dubbo源码解析之ReferenceBean_referencebean.get() failed to check the status of

referencebean.get() failed to check the status of the service

一个dubbo服务需要 api、provider、consumer构成

api提供接口供provider和consumer引用

1、接口的实现类需要用

org.apache.dubbo.config.annotation.Service包的@Service注解
  1. @Service(version = "1.0.1")
  2. public class ExampleImpl implements ExampleService {
  3. @Override
  4. public String sayHello() {
  5. return "new springboot dubbo project";
  6. }
  7. }

区别于Spring的@Service注解

 

2、接口的引用方需要

org.apache.dubbo.config.annotation.Reference包的@Reference

形如:

  1. //本地服务
  2. @Autowired
  3. LocalService localService;
  4. //dubbo服务
  5. @Reference
  6. ExampleService exampleService;

 

可能使用起来会有同学觉得不方便,无论是实现还是引用可不可以只用Spring的注解呢,这时需要ReferenceBean出马了

使用方法,由provider新建moduel-client供consumer调用,client引用api

  1. @Bean
  2. public ReferenceBean<PLConfigService> configServiceReferenceBean(){
  3. ReferenceBean<PLConfigService> referenceBean = new ReferenceBean<>();
  4. referenceBean.setInterface(PLConfigService.class);
  5. referenceBean.setCheck(false);
  6. return referenceBean;
  7. }
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {...}

ReferenceBean实现了InitializingBean接口的afterPropertiesSet(),所以Spring会在初始化该类的属性后调用afterPropertiesSet方法

入口:

  1. public void afterPropertiesSet() throws Exception {
  2. //加载ConsumerConfig
  3. if (getConsumer() == null) {
  4. Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false);
  5. if (consumerConfigMap != null && consumerConfigMap.size() > 0) {
  6. ConsumerConfig consumerConfig = null;
  7. for (ConsumerConfig config : consumerConfigMap.values()) {
  8. if (config.isDefault() == null || config.isDefault().booleanValue()) {
  9. if (consumerConfig != null) {
  10. throw new IllegalStateException("Duplicate consumer configs: " + consumerConfig + " and " + config);
  11. }
  12. consumerConfig = config;
  13. }
  14. }
  15. if (consumerConfig != null) {
  16. setConsumer(consumerConfig);
  17. }
  18. }
  19. }
  20.   //加载应用上下文
  21. if (getApplication() == null
  22. && (getConsumer() == null || getConsumer().getApplication() == null)) {
  23. Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
  24. if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
  25. ApplicationConfig applicationConfig = null;
  26. for (ApplicationConfig config : applicationConfigMap.values()) {
  27. if (config.isDefault() == null || config.isDefault().booleanValue()) {
  28. if (applicationConfig != null) {
  29. throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
  30. }
  31. applicationConfig = config;
  32. }
  33. }
  34. if (applicationConfig != null) {
  35. setApplication(applicationConfig);
  36. }
  37. }
  38. }
  39.   //加载ModuleConfig
  40. if (getModule() == null
  41. && (getConsumer() == null || getConsumer().getModule() == null)) {
  42. Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
  43. if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
  44. ModuleConfig moduleConfig = null;
  45. for (ModuleConfig config : moduleConfigMap.values()) {
  46. if (config.isDefault() == null || config.isDefault().booleanValue()) {
  47. if (moduleConfig != null) {
  48. throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
  49. }
  50. moduleConfig = config;
  51. }
  52. }
  53. if (moduleConfig != null) {
  54. setModule(moduleConfig);
  55. }
  56. }
  57. }
  58. //加载RegistryConfig
  59. if ((getRegistries() == null || getRegistries().size() == 0)
  60. && (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().size() == 0)
  61. && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
  62. Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
  63. if (registryConfigMap != null && registryConfigMap.size() > 0) {
  64. List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
  65. for (RegistryConfig config : registryConfigMap.values()) {
  66. if (config.isDefault() == null || config.isDefault().booleanValue()) {
  67. registryConfigs.add(config);
  68. }
  69. }
  70. if (registryConfigs != null && registryConfigs.size() > 0) {
  71. super.setRegistries(registryConfigs);
  72. }
  73. }
  74. }
  75.   //加载MonitorConfig
  76. if (getMonitor() == null
  77. && (getConsumer() == null || getConsumer().getMonitor() == null)
  78. && (getApplication() == null || getApplication().getMonitor() == null)) {
  79. Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
  80. if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
  81. MonitorConfig monitorConfig = null;
  82. for (MonitorConfig config : monitorConfigMap.values()) {
  83. if (config.isDefault() == null || config.isDefault().booleanValue()) {
  84. if (monitorConfig != null) {
  85. throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
  86. }
  87. monitorConfig = config;
  88. }
  89. }
  90. if (monitorConfig != null) {
  91. setMonitor(monitorConfig);
  92. }
  93. }
  94. }
  95. //以上config都在DubboAutoConfiguration中加载进了Spring容器中
  96. Boolean b = isInit();
  97. if (b == null && getConsumer() != null) {
  98. b = getConsumer().isInit();
  99. }
  100. if (b != null && b.booleanValue()) {
  101.   //重点 这一步会将之前set的interface加载进来
  102. getObject();
  103. }
  104. }
  1. public Object getObject() throws Exception {
  2. return get();
  3. }

get()是父类ReferenceConfig<T>的方法,T为传入的接口的类型

  1. // 接口代理类引用
  2. private transient volatile T ref;
  1. public synchronized T get() {
  2. if (destroyed) {
  3. throw new IllegalStateException("Already destroyed!");
  4. }
  5. if (ref == null) {
  6.   //初始化
  7. init();
  8. }
  9. return ref;
  10. }

我们setInterface时

  1. public void setInterface(Class<?> interfaceClass) {
  2. if (interfaceClass != null && !interfaceClass.isInterface()) {
  3. throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
  4. }
  5. this.interfaceClass = interfaceClass;
  6. setInterface(interfaceClass == null ? (String) null : interfaceClass.getName());
  7. }
  8. public void setInterface(String interfaceName) {
  9. this.interfaceName = interfaceName;
  10. if (id == null || id.length() == 0) {
  11. id = interfaceName;
  12. }
  13. }
  1. private void init() {
  2. //...省略N行
  3. //
  4. checkStubAndMock(interfaceClass);
  5. //...
  6. ref = createProxy(map);
  7. }
  1. private T createProxy(Map<String, String> map) {
  2. URL tmpUrl = new URL("temp", "localhost", 0, map);
  3. final boolean isJvmRefer;
  4. if (isInjvm() == null) {
  5. if (url != null && url.length() > 0) { //指定URL的情况下,不做本地引用
  6. isJvmRefer = false;
  7. } else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
  8. //默认情况下如果本地有服务暴露,则引用本地服务.
  9. isJvmRefer = true;
  10. } else {
  11. isJvmRefer = false;
  12. }
  13. } else {
  14. isJvmRefer = isInjvm().booleanValue();
  15. }
  16. if (isJvmRefer) {
  17. URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
  18. invoker = refprotocol.refer(interfaceClass, url);
  19. if (logger.isInfoEnabled()) {
  20. logger.info("Using injvm service " + interfaceClass.getName());
  21. }
  22. } else {
  23. if (url != null && url.length() > 0) { // 用户指定URL,指定的URL可能是对点对直连地址,也可能是注册中心URL
  24. String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
  25. if (us != null && us.length > 0) {
  26. for (String u : us) {
  27. URL url = URL.valueOf(u);
  28. if (url.getPath() == null || url.getPath().length() == 0) {
  29. url = url.setPath(interfaceName);
  30. }
  31. if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
  32. urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
  33. } else {
  34. urls.add(ClusterUtils.mergeUrl(url, map));
  35. }
  36. }
  37. }
  38. } else { // 通过注册中心配置拼装URL
  39. List<URL> us = loadRegistries(false);
  40. if (us != null && us.size() > 0) {
  41. for (URL u : us) {
  42. URL monitorUrl = loadMonitor(u);
  43. if (monitorUrl != null) {
  44. map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
  45. }
  46. urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
  47. }
  48. }
  49. if (urls == null || urls.size() == 0) {
  50. throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
  51. }
  52. }
  53. if (urls.size() == 1) {
  54. invoker = refprotocol.refer(interfaceClass, urls.get(0));
  55. } else {
  56. List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
  57. URL registryURL = null;
  58. for (URL url : urls) {
  59. invokers.add(refprotocol.refer(interfaceClass, url));
  60. if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
  61. registryURL = url; // 用了最后一个registry url
  62. }
  63. }
  64. if (registryURL != null) { // 有 注册中心协议的URL
  65. // 对有注册中心的Cluster 只用 AvailableCluster
  66. URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
  67. invoker = cluster.join(new StaticDirectory(u, invokers));
  68. } else { // 不是 注册中心的URL
  69. invoker = cluster.join(new StaticDirectory(invokers));
  70. }
  71. }
  72. }
  73. Boolean c = check;
  74. if (c == null && consumer != null) {
  75. c = consumer.isCheck();
  76. }
  77. if (c == null) {
  78. c = true; // default true
  79. }
  80. if (c && !invoker.isAvailable()) {
  81. throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
  82. }
  83. if (logger.isInfoEnabled()) {
  84. logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
  85. }
  86. // 创建服务代理
  87. return (T) proxyFactory.getProxy(invoker);
  88. }

 

 

 

 

 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/165835
推荐阅读
相关标签
  

闽ICP备14008679号