diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java index fa6dac0a2..cbab596b6 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java @@ -20,12 +20,15 @@ import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.config.spring.util.PropertySourcesUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; +import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler; +import org.springframework.cloud.alibaba.dubbo.registry.handler.StandardDubboRegistryServiceIdHandler; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; import org.springframework.cloud.alibaba.dubbo.service.parameter.PathVariableServiceParameterResolver; import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver; import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestHeaderServiceParameterResolver; import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -67,6 +70,11 @@ public class DubboServiceAutoConfiguration { static class ParameterResolversConfiguration { } + @Bean + @ConditionalOnMissingBean + public DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler(ConfigurableApplicationContext context) { + return new StandardDubboRegistryServiceIdHandler(context); + } /** * Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459 diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java index 42efe71d6..14cc3ac60 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java @@ -30,16 +30,16 @@ import java.util.Set; @JsonInclude(JsonInclude.Include.NON_NULL) public class ServiceRestMetadata { - private String name; + private String url; private Set meta; - public String getName() { - return name; + public String getUrl() { + return url; } - public void setName(String name) { - this.name = name; + public void setUrl(String url) { + this.url = url; } public Set getMeta() { @@ -55,12 +55,12 @@ public class ServiceRestMetadata { if (this == o) return true; if (!(o instanceof ServiceRestMetadata)) return false; ServiceRestMetadata that = (ServiceRestMetadata) o; - return Objects.equals(name, that.name) && + return Objects.equals(url, that.url) && Objects.equals(meta, that.meta); } @Override public int hashCode() { - return Objects.hash(name, meta); + return Objects.hash(url, meta); } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboServiceBeanMetadataResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboServiceBeanMetadataResolver.java index 31e2d2205..22b0b3d29 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboServiceBeanMetadataResolver.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboServiceBeanMetadataResolver.java @@ -28,7 +28,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; -import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry; import org.springframework.util.ClassUtils; import java.lang.reflect.Method; @@ -115,10 +114,10 @@ public class DubboServiceBeanMetadataResolver implements BeanClassLoaderAware, S List urls = serviceBean.getExportedUrls(); urls.stream() - .map(SpringCloudRegistry::getServiceName) - .forEach(serviceName -> { + .map(URL::toString) + .forEach(url -> { ServiceRestMetadata metadata = new ServiceRestMetadata(); - metadata.setName(serviceName); + metadata.setUrl(url); metadata.setMeta(methodRestMetadata); serviceRestMetadata.add(metadata); }); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java index d0465342f..8cd299986 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java @@ -18,10 +18,11 @@ package org.springframework.cloud.alibaba.dubbo.registry; import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.NetUtils; +import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.context.ConfigurableApplicationContext; import java.util.LinkedHashMap; @@ -29,20 +30,49 @@ import java.util.LinkedHashMap; * Abstract {@link RegistrationFactory} implementation *

* - * @param The subclass of {@link Registration} + * @param The subclass of {@link Registration} * @author Mercy */ -public abstract class AbstractRegistrationFactory implements RegistrationFactory { +public abstract class AbstractRegistrationFactory implements RegistrationFactory { - protected ServiceInstance createServiceInstance(String serviceName, URL url) { + public final R create(URL url, ConfigurableApplicationContext applicationContext) { + ServiceInstance serviceInstance = createServiceInstance(url, applicationContext); + return create(url, applicationContext, serviceInstance); + } + + /** + * Sub-class should override this method to create an instance of {@link R} + * + * @param url The Dubbo's {@link URL} + * @param applicationContext {@link ConfigurableApplicationContext} + * @param serviceInstance {@link ServiceInstance} + * @return nullable + */ + protected abstract R create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance); + + /** + * Create an instance {@link ServiceInstance}. This method maybe override by sub-class. + * + * @param url The Dubbo's {@link URL} + * @param applicationContext {@link ConfigurableApplicationContext} + * @return an instance {@link ServiceInstance} + */ + protected ServiceInstance createServiceInstance(URL url, ConfigurableApplicationContext applicationContext) { + String serviceId = createServiceId(url, applicationContext); // Append default category if absent String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); URL newURL = url.addParameter(Constants.CATEGORY_KEY, category); newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol()); - String ip = NetUtils.getLocalHost(); + String ip = url.getIp(); int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort()); - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceName, ip, port, false); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceId, ip, port, false); serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters())); return serviceInstance; } + + protected String createServiceId(URL url, ConfigurableApplicationContext applicationContext) { + DubboRegistryServiceIdHandler handler = applicationContext.getBean(DubboRegistryServiceIdHandler.class); + return handler.createServiceId(url); + } } + diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java index d9960574e..308657684 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java @@ -17,8 +17,9 @@ package org.springframework.cloud.alibaba.dubbo.registry; import org.apache.dubbo.common.URL; +import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; /** * Default {@link RegistrationFactory} @@ -28,7 +29,7 @@ import org.springframework.context.ApplicationContext; public class DefaultRegistrationFactory extends AbstractRegistrationFactory { @Override - public Registration create(String serviceName, URL url, ApplicationContext applicationContext) { - return new DelegatingRegistration(createServiceInstance(serviceName, url)); + protected Registration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) { + return new DelegatingRegistration(serviceInstance); } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java index d7c347121..d7d977374 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java @@ -18,24 +18,23 @@ package org.springframework.cloud.alibaba.dubbo.registry; import org.apache.dubbo.common.URL; import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; /** * {@link Registration} Factory to createServiceInstance a instance of {@link Registration} * - * @param The subclass of {@link Registration} + * @param The subclass of {@link Registration} * @author Mercy */ -public interface RegistrationFactory { +public interface RegistrationFactory { /** - * Create a instance of {@link T} + * Create a instance of {@link R} * - * @param serviceName The service name of Dubbo service interface - * @param url The Dubbo's URL - * @param applicationContext {@link ApplicationContext} - * @return a instance of {@link T} + * @param url The Dubbo's {@link URL} + * @param applicationContext {@link ConfigurableApplicationContext} + * @return a instance of {@link R}, if null, it indicates the registration will not be executed. */ - T create(String serviceName, URL url, ApplicationContext applicationContext); + R create(URL url, ConfigurableApplicationContext applicationContext); } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java index 99222a4da..d87e1f6c1 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java @@ -18,44 +18,35 @@ package org.springframework.cloud.alibaba.dubbo.registry; import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.RegistryFactory; import org.apache.dubbo.registry.support.FailbackRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.context.ApplicationContext; -import org.springframework.core.ResolvableType; -import org.springframework.util.StringUtils; +import org.springframework.context.ConfigurableApplicationContext; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Objects; +import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY; -import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY; -import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY; -import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY; -import static java.lang.Long.getLong; -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; -import static org.springframework.beans.BeanUtils.instantiateClass; -import static org.springframework.core.ResolvableType.forInstance; -import static org.springframework.core.ResolvableType.forType; -import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames; -import static org.springframework.util.ClassUtils.isPresent; -import static org.springframework.util.ClassUtils.resolveClassName; +import static java.util.Collections.singletonList; +import static org.apache.dubbo.common.Constants.CONFIGURATORS_CATEGORY; +import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY; +import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY; +import static org.apache.dubbo.common.Constants.PROVIDER_SIDE; +import static org.apache.dubbo.common.Constants.ROUTERS_CATEGORY; +import static org.apache.dubbo.common.Constants.SIDE_KEY; /** * Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud" @@ -64,169 +55,96 @@ import static org.springframework.util.ClassUtils.resolveClassName; */ public class SpringCloudRegistry extends FailbackRegistry { + /** + * The parameter name of {@link #allServicesLookupInterval} + */ + public static final String ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.all.services.lookup.interval"; + + /** + * The parameter name of {@link #registeredServicesLookupInterval} + */ + public static final String REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.registered.services.lookup.interval"; + /** * All supported categories */ - private static final String[] ALL_SUPPORTED_CATEGORIES = of( + public static final String[] ALL_SUPPORTED_CATEGORIES = of( PROVIDERS_CATEGORY, CONSUMERS_CATEGORY, ROUTERS_CATEGORY, CONFIGURATORS_CATEGORY ); - private static final int CATEGORY_INDEX = 0; - - private static final int SERVICE_INTERFACE_INDEX = CATEGORY_INDEX + 1; - - private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1; - - private static final int SERVICE_GROUP_INDEX = SERVICE_VERSION_INDEX + 1; - - private static final String WILDCARD = "*"; + private final Logger logger = LoggerFactory.getLogger(getClass()); /** * The interval in second of lookup service names(only for Dubbo-OPS) */ - private static final long ALL_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.all.services.lookup.interval", 30); + private final long allServicesLookupInterval; - /** - * The interval in second of lookup regigered service instances - */ - private static final long REGISTERED_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.registered.services.lookup.interval", 300); + private final long registeredServicesLookupInterval; - /** - * The {@link ScheduledExecutorService Scheduler} to lookup the registered services - */ - private static final ScheduledExecutorService registeredServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-registered-services-lookup-")); + private final ServiceRegistry serviceRegistry; - /** - * The {@link ScheduledExecutorService Scheduler} to lookup all services (only for Dubbo-OPS) - */ - private static volatile ScheduledExecutorService allServicesLookupScheduler; + private final RegistrationFactory registrationFactory; - private final Logger logger = LoggerFactory.getLogger(getClass()); + private final DiscoveryClient discoveryClient; - /** - * The separator for service name - */ - private static final String SERVICE_NAME_SEPARATOR = ":"; + private final DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler; - private final ApplicationContext applicationContext; + private final ScheduledExecutorService servicesLookupScheduler; - private final ServiceRegistry serviceRegistry; + private final ConfigurableApplicationContext applicationContext; - private final DiscoveryClient discoveryClient; - - private final RegistrationFactory registrationFactory; - - public SpringCloudRegistry(URL url, ApplicationContext applicationContext) { + public SpringCloudRegistry(URL url, + ServiceRegistry serviceRegistry, + RegistrationFactory registrationFactory, + DiscoveryClient discoveryClient, + ScheduledExecutorService servicesLookupScheduler, + ConfigurableApplicationContext applicationContext) { super(url); + this.allServicesLookupInterval = url.getParameter(ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 30L); + this.registeredServicesLookupInterval = url.getParameter(REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 300L); + this.serviceRegistry = serviceRegistry; + this.registrationFactory = registrationFactory; + this.discoveryClient = discoveryClient; + this.dubboRegistryServiceIdHandler = applicationContext.getBean(DubboRegistryServiceIdHandler.class); this.applicationContext = applicationContext; - this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class); - this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader()); - this.discoveryClient = applicationContext.getBean(DiscoveryClient.class); - applicationContext.getClassLoader(); + this.servicesLookupScheduler = servicesLookupScheduler; } - private RegistrationFactory buildRegistrationFactory(ServiceRegistry serviceRegistry, - ClassLoader classLoader) { - RegistrationFactory registrationFactory = null; - List factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader); - - ResolvableType serviceRegistryType = forInstance(serviceRegistry); - // Get first generic Class - Class registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0); - - for (String factoryClassName : factoryClassNames) { - if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue - Class factoryClass = resolveClassName(factoryClassName, classLoader); - ResolvableType registrationFactoryType = forType(factoryClass); - Class actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0); - if (registrationClass.equals(actualRegistrationClass)) { - registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass()); - break; - } - } - } - - if (registrationFactory == null) { - - if (logger.isWarnEnabled()) { - logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]", - registrationClass.getSimpleName(), serviceRegistry.getClass().getName()); - } - - registrationFactory = new DefaultRegistrationFactory(); - } else { - if (logger.isInfoEnabled()) { - logger.info("{} has been resolved by ServiceRegistry[{}]", - registrationFactory.getClass().getName(), serviceRegistry.getClass().getName()); - } - } - - return registrationFactory; + protected boolean shouldRegister(Registration registration) { + Map metadata = registration.getMetadata(); + String side = metadata.get(SIDE_KEY); + return PROVIDER_SIDE.equals(side); // Only register the Provider. } - private Class resolveGenericClass(ResolvableType implementedType, Class interfaceClass, int index) { - - ResolvableType resolvableType = implementedType; - - try { - OUTER: - while (true) { - - ResolvableType[] interfaceTypes = resolvableType.getInterfaces(); - - for (ResolvableType interfaceType : interfaceTypes) { - if (interfaceType.resolve().equals(interfaceClass)) { - resolvableType = interfaceType; - break OUTER; - } - } - - ResolvableType superType = resolvableType.getSuperType(); - - Class superClass = superType.resolve(); - - if (Object.class.equals(superClass)) { - break; - } - - resolvableType = superType; - } - - } catch (Throwable e) { - resolvableType = ResolvableType.forType(void.class); - } - - return resolvableType.resolveGeneric(index); - } - - @Override public void doRegister(URL url) { - final String serviceName = getServiceName(url); - final Registration registration = createRegistration(serviceName, url); - serviceRegistry.register(registration); + final Registration registration = createRegistration(url); + if (shouldRegister(registration)) { + serviceRegistry.register(registration); + } } @Override public void doUnregister(URL url) { - final String serviceName = getServiceName(url); - final Registration registration = createRegistration(serviceName, url); - this.serviceRegistry.deregister(registration); + final Registration registration = createRegistration(url); + if (shouldRegister(registration)) { + this.serviceRegistry.deregister(registration); + } } @Override public void doSubscribe(URL url, NotifyListener listener) { List serviceNames = getServiceNames(url, listener); doSubscribe(url, listener, serviceNames); - this.registeredServicesLookupScheduler.scheduleAtFixedRate(new Runnable() { + this.servicesLookupScheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { doSubscribe(url, listener, serviceNames); } - }, REGISTERED_SERVICES_LOOKUP_INTERVAL, REGISTERED_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS); + }, registeredServicesLookupInterval, registeredServicesLookupInterval, TimeUnit.SECONDS); } @Override @@ -234,136 +152,34 @@ public class SpringCloudRegistry extends FailbackRegistry { if (isAdminProtocol(url)) { shutdownServiceNamesLookup(); } - -// if (registeredServicesLookupScheduler != null) { -// registeredServicesLookupScheduler.shutdown(); -// } } @Override public boolean isAvailable() { - return false; + return !discoveryClient.getServices().isEmpty(); } private void shutdownServiceNamesLookup() { - if (allServicesLookupScheduler != null) { - allServicesLookupScheduler.shutdown(); + if (servicesLookupScheduler != null) { + servicesLookupScheduler.shutdown(); } } - private Registration createRegistration(String serviceName, URL url) { - return registrationFactory.create(serviceName, url, applicationContext); - } - - public static String getServiceName(URL url) { - String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); - return getServiceName(url, category); - } - - private static String getServiceName(URL url, String category) { - StringBuilder serviceNameBuilder = new StringBuilder(category); - appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY); - appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY); - appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY); - return serviceNameBuilder.toString(); - } - - private static void appendIfPresent(StringBuilder target, URL url, String parameterName) { - String parameterValue = url.getParameter(parameterName); - appendIfPresent(target, parameterValue); - } - - private static void appendIfPresent(StringBuilder target, String parameterValue) { - if (StringUtils.hasText(parameterValue)) { - target.append(SERVICE_NAME_SEPARATOR).append(parameterValue); - } + private Registration createRegistration(URL url) { + return registrationFactory.create(url, applicationContext); } - private void filterServiceNames(List serviceNames, URL url) { - - final String[] categories = getCategories(url); - - final String targetServiceInterface = url.getServiceInterface(); - - final String targetVersion = url.getParameter(Constants.VERSION_KEY); - - final String targetGroup = url.getParameter(Constants.GROUP_KEY); - + private void filterServiceNames(List serviceNames) { filter(serviceNames, new Filter() { @Override public boolean accept(String serviceName) { - // split service name to segments - // (required) segments[0] = category - // (required) segments[1] = serviceInterface - // (required) segments[2] = version - // (optional) segments[3] = group - String[] segments = getServiceSegments(serviceName); - int length = segments.length; - if (length < SERVICE_GROUP_INDEX) { // must present 4 segments or more - return false; - } - - String category = getCategory(segments); - if (Arrays.binarySearch(categories, category) > -1) { // no match category - return false; - } - - String serviceInterface = getServiceInterface(segments); - if (!WILDCARD.equals(targetServiceInterface) && - !Objects.equals(targetServiceInterface, serviceInterface)) { // no match service interface - return false; - } - - String version = getServiceVersion(segments); - if (!WILDCARD.equals(targetVersion) && - !Objects.equals(targetVersion, version)) { // no match service version - return false; - } - - String group = getServiceGroup(segments); - if (group != null && !WILDCARD.equals(targetGroup) - && !Objects.equals(targetGroup, group)) { // no match service group - return false; - } - - return true; + return dubboRegistryServiceIdHandler.supports(serviceName); } }); } - public static String[] getServiceSegments(String serviceName) { - return StringUtils.delimitedListToStringArray(serviceName, SERVICE_NAME_SEPARATOR); - } - - public static String getCategory(String[] segments) { - return segments[CATEGORY_INDEX]; - } - - public static String getServiceInterface(String[] segments) { - return segments[SERVICE_INTERFACE_INDEX]; - } - - public static String getServiceVersion(String[] segments) { - return segments[SERVICE_VERSION_INDEX]; - } - - public static String getServiceGroup(String[] segments) { - return segments.length > SERVICE_GROUP_INDEX ? segments[SERVICE_GROUP_INDEX] : null; - } - - /** - * Get the categories from {@link URL} - * - * @param url {@link URL} - * @return non-null array - */ - private String[] getCategories(URL url) { - return Constants.ANY_VALUE.equals(url.getServiceInterface()) ? - ALL_SUPPORTED_CATEGORIES : of(Constants.DEFAULT_CATEGORY); - } - private List getAllServiceNames() { - return discoveryClient.getServices(); + return new LinkedList<>(discoveryClient.getServices()); } /** @@ -378,7 +194,7 @@ public class SpringCloudRegistry extends FailbackRegistry { initAllServicesLookupScheduler(url, listener); return getServiceNamesForOps(url); } else { - return doGetServiceNames(url); + return singletonList(dubboRegistryServiceIdHandler.createServiceId(url)); } } @@ -388,30 +204,14 @@ public class SpringCloudRegistry extends FailbackRegistry { } private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) { - if (allServicesLookupScheduler == null) { - allServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-all-services-lookup-")); - allServicesLookupScheduler.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - List serviceNames = getAllServiceNames(); - filter(serviceNames, new Filter() { - @Override - public boolean accept(String serviceName) { - boolean accepted = false; - for (String category : ALL_SUPPORTED_CATEGORIES) { - String prefix = category + SERVICE_NAME_SEPARATOR; - if (StringUtils.startsWithIgnoreCase(serviceName, prefix)) { - accepted = true; - break; - } - } - return accepted; - } - }); - doSubscribe(url, listener, serviceNames); - } - }, ALL_SERVICES_LOOKUP_INTERVAL, ALL_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS); - } + servicesLookupScheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + List serviceNames = getAllServiceNames(); + filterServiceNames(serviceNames); + doSubscribe(url, listener, serviceNames); + } + }, allServicesLookupInterval, allServicesLookupInterval, TimeUnit.SECONDS); } private void doSubscribe(final URL url, final NotifyListener listener, final List serviceNames) { @@ -421,16 +221,6 @@ public class SpringCloudRegistry extends FailbackRegistry { } } - private List doGetServiceNames(URL url) { - String[] categories = getCategories(url); - List serviceNames = new ArrayList(categories.length); - for (String category : categories) { - final String serviceName = getServiceName(url, category); - serviceNames.add(serviceName); - } - return serviceNames; - } - /** * Notify the Healthy {@link ServiceInstance service instance} to subscriber. * @@ -487,7 +277,7 @@ public class SpringCloudRegistry extends FailbackRegistry { */ private List getServiceNamesForOps(URL url) { List serviceNames = getAllServiceNames(); - filterServiceNames(serviceNames, url); + filterServiceNames(serviceNames); return serviceNames; } @@ -508,7 +298,7 @@ public class SpringCloudRegistry extends FailbackRegistry { /** * A filter */ - private interface Filter { + public interface Filter { /** * Tests whether or not the specified data should be accepted. diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java index 803298536..3ff199c92 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java @@ -17,9 +17,28 @@ package org.springframework.cloud.alibaba.dubbo.registry; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; -import org.springframework.context.ApplicationContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ResolvableType; + +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; + +import static java.lang.System.getProperty; +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; +import static org.springframework.beans.BeanUtils.instantiateClass; +import static org.springframework.core.ResolvableType.forInstance; +import static org.springframework.core.ResolvableType.forType; +import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames; +import static org.springframework.util.ClassUtils.isPresent; +import static org.springframework.util.ClassUtils.resolveClassName; /** * Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud" @@ -30,14 +49,122 @@ import org.springframework.context.ApplicationContext; */ public class SpringCloudRegistryFactory implements RegistryFactory { - private static ApplicationContext applicationContext; + private static String SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX = + getProperty("dubbo.services.lookup.scheduler.thread.name.prefix ", "dubbo-services-lookup-"); + + private static ConfigurableApplicationContext applicationContext; + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final ScheduledExecutorService servicesLookupScheduler; + + private ServiceRegistry serviceRegistry; + + private RegistrationFactory registrationFactory; + + private DiscoveryClient discoveryClient; + + private volatile boolean initialized = false; + + public SpringCloudRegistryFactory() { + servicesLookupScheduler = newSingleThreadScheduledExecutor( + new NamedThreadFactory(SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX)); + } + + protected void init() { + if (initialized || applicationContext == null) { + return; + } + + this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class); + this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader()); + this.discoveryClient = applicationContext.getBean(DiscoveryClient.class); + } @Override public Registry getRegistry(URL url) { - return new SpringCloudRegistry(url, applicationContext); + init(); + return new SpringCloudRegistry(url, serviceRegistry, registrationFactory, discoveryClient, + servicesLookupScheduler, applicationContext); } - public static void setApplicationContext(ApplicationContext applicationContext) { + public static void setApplicationContext(ConfigurableApplicationContext applicationContext) { SpringCloudRegistryFactory.applicationContext = applicationContext; } + + + private RegistrationFactory buildRegistrationFactory(ServiceRegistry serviceRegistry, + ClassLoader classLoader) { + RegistrationFactory registrationFactory = null; + List factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader); + + ResolvableType serviceRegistryType = forInstance(serviceRegistry); + // Get first generic Class + Class registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0); + + for (String factoryClassName : factoryClassNames) { + if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue + Class factoryClass = resolveClassName(factoryClassName, classLoader); + ResolvableType registrationFactoryType = forType(factoryClass); + Class actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0); + if (registrationClass.equals(actualRegistrationClass)) { + registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass()); + break; + } + } + } + + if (registrationFactory == null) { + + if (logger.isWarnEnabled()) { + logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]", + registrationClass.getSimpleName(), serviceRegistry.getClass().getName()); + } + + registrationFactory = new DefaultRegistrationFactory(); + } else { + if (logger.isInfoEnabled()) { + logger.info("{} has been resolved by ServiceRegistry[{}]", + registrationFactory.getClass().getName(), serviceRegistry.getClass().getName()); + } + } + + return registrationFactory; + } + + private Class resolveGenericClass(ResolvableType implementedType, Class interfaceClass, int index) { + + ResolvableType resolvableType = implementedType; + + try { + OUTER: + while (true) { + + ResolvableType[] interfaceTypes = resolvableType.getInterfaces(); + + for (ResolvableType interfaceType : interfaceTypes) { + if (interfaceType.resolve().equals(interfaceClass)) { + resolvableType = interfaceType; + break OUTER; + } + } + + ResolvableType superType = resolvableType.getSuperType(); + + Class superClass = superType.resolve(); + + if (Object.class.equals(superClass)) { + break; + } + + resolvableType = superType; + } + + } catch (Throwable e) { + resolvableType = ResolvableType.forType(void.class); + } + + return resolvableType.resolveGeneric(index); + } + } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java index e065a6e75..d24e9e718 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java @@ -23,7 +23,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance; import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration; import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; /** * Zookeeper {@link RegistrationFactory} @@ -33,10 +33,7 @@ import org.springframework.context.ApplicationContext; public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory { @Override - public ZookeeperRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { - - ServiceInstance serviceInstance = createServiceInstance(serviceName, url); - + protected ZookeeperRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) { ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(), serviceInstance.getServiceId(), serviceInstance.getMetadata()); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java new file mode 100644 index 000000000..15a350291 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.alibaba.dubbo.registry.handler; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.registry.Registry; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * Dubbo {@link Registry} Spring Cloud Service Id Builder + * + * @author Mercy + */ +public interface DubboRegistryServiceIdHandler { + + /** + * Supports the specified id of Spring Cloud Service or not + * + * @param serviceId the specified id of Spring Cloud Service + * @return if supports, return true, or false + */ + boolean supports(String serviceId); + + /** + * Creates the id of Spring Cloud Service + * + * @param url The Dubbo's {@link URL} + * @return non-null + */ + String createServiceId(URL url); + + /** + * The instance if {@link ConfigurableApplicationContext} . + * + * @return non-null + */ + ConfigurableApplicationContext getContext(); + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java new file mode 100644 index 000000000..caaa07060 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.alibaba.dubbo.registry.handler; + +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.URL; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.util.StringUtils; + +import java.util.Objects; + +import static java.lang.System.getProperty; +import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY; +import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY; +import static org.springframework.util.StringUtils.startsWithIgnoreCase; + +/** + * The Standard {@link DubboRegistryServiceIdHandler} + *

+ * The service ID pattern is "${category}:${interface}:${version}:${group}" + * + * @author Mercy + */ +public class StandardDubboRegistryServiceIdHandler implements DubboRegistryServiceIdHandler { + + /** + * The separator for service name that could be changed by the Java Property "dubbo.service.name.separator". + */ + protected static final String SERVICE_NAME_SEPARATOR = getProperty("dubbo.service.name.separator", ":"); + + private final ConfigurableApplicationContext context; + + public StandardDubboRegistryServiceIdHandler(ConfigurableApplicationContext context) { + this.context = context; + } + + @Override + public boolean supports(String serviceId) { + return startsWithIgnoreCase(serviceId, PROVIDERS_CATEGORY) || + startsWithIgnoreCase(serviceId, CONSUMERS_CATEGORY); + } + + @Override + public String createServiceId(URL url) { + String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); + if (!Objects.equals(category, PROVIDERS_CATEGORY) && !Objects.equals(category, CONSUMERS_CATEGORY)) { + category = PROVIDERS_CATEGORY; + } + return createServiceId(url, category); + } + + @Override + public ConfigurableApplicationContext getContext() { + return context; + } + + /** + * This method maybe override by sub-class. + * + * @param url The Dubbo's {@link URL} + * @param category The category + * @return + */ + protected String createServiceId(URL url, String category) { + StringBuilder serviceNameBuilder = new StringBuilder(category); + appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY); + appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY); + appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY); + return serviceNameBuilder.toString(); + } + + private static void appendIfPresent(StringBuilder target, URL url, String parameterName) { + String parameterValue = url.getParameter(parameterName); + appendIfPresent(target, parameterValue); + } + + private static void appendIfPresent(StringBuilder target, String parameterValue) { + if (StringUtils.hasText(parameterValue)) { + target.append(SERVICE_NAME_SEPARATOR).append(parameterValue); + } + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java index c287570cb..8fd93a658 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java @@ -24,7 +24,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.cloud.consul.discovery.ConsulServerUtils; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -40,9 +40,7 @@ import java.util.Set; public class ConsulRegistrationFactory extends AbstractRegistrationFactory { @Override - public ConsulRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { - ServiceInstance serviceInstance = createServiceInstance(serviceName, url); - + protected ConsulRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) { Map metadata = getMetadata(serviceInstance); List tags = createTags(metadata); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java index 8b918e276..486154f59 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java @@ -27,7 +27,7 @@ import org.springframework.cloud.commons.util.InetUtils; import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig; import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; -import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; /** * {@link EurekaRegistration} Factory @@ -37,8 +37,7 @@ import org.springframework.context.ApplicationContext; public class EurekaRegistrationFactory extends AbstractRegistrationFactory { @Override - public EurekaRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { - ServiceInstance serviceInstance = createServiceInstance(serviceName, url); + protected EurekaRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) { CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class); ObjectProvider healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class); EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java index 2cfe20295..e15bbb692 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java @@ -16,6 +16,7 @@ */ package org.springframework.cloud.alibaba.dubbo.service; +import org.apache.dubbo.common.URL; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.rpc.service.GenericService; import org.slf4j.Logger; @@ -30,12 +31,10 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static com.alibaba.dubbo.common.Constants.DEFAULT_CLUSTER; -import static com.alibaba.dubbo.common.Constants.DEFAULT_PROTOCOL; -import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup; -import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface; -import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments; -import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion; +import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER; +import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL; +import static org.apache.dubbo.common.Constants.GROUP_KEY; +import static org.apache.dubbo.common.Constants.VERSION_KEY; /** * Dubbo {@link GenericService} Factory @@ -66,11 +65,11 @@ public class DubboGenericServiceFactory { private ReferenceBean build(ServiceRestMetadata serviceRestMetadata, DubboTransportedMetadata dubboTransportedMetadata) { - String dubboServiceName = serviceRestMetadata.getName(); - String[] segments = getServiceSegments(dubboServiceName); - String interfaceName = getServiceInterface(segments); - String version = getServiceVersion(segments); - String group = getServiceGroup(segments); + String urlValue = serviceRestMetadata.getUrl(); + URL url = URL.valueOf(urlValue); + String interfaceName = url.getServiceInterface(); + String version = url.getParameter(VERSION_KEY); + String group = url.getParameter(GROUP_KEY); String protocol = dubboTransportedMetadata.getProtocol(); String cluster = dubboTransportedMetadata.getCluster(); diff --git a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories index f90bb175a..829c004ea 100644 --- a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories @@ -9,7 +9,6 @@ org.springframework.context.ApplicationContextInitializer=\ org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\ - org.springframework.cloud.alibaba.dubbo.registry.DefaultRegistrationFactory,\ org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka.EurekaRegistrationFactory,\ org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\ org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml index 83d0d8354..d2b72d471 100644 --- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml +++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml @@ -1,5 +1,8 @@ dubbo: registry: - address: spring-cloud://nacos +# The Spring Cloud Dubbo's registry extension + address: spring-cloud://localhost +# The traditional Dubbo's registry +# address: zookeeper://127.0.0.1:2181 server: port: 7070 \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml index 2b3eb54e9..0f6094acb 100644 --- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml +++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml @@ -10,7 +10,10 @@ dubbo: port: 8081 server: netty registry: - address: spring-cloud://nacos +# The Spring Cloud Dubbo's registry extension + address: spring-cloud://localhost +# The traditional Dubbo's registry +# address: zookeeper://127.0.0.1:2181 feign: hystrix: