1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00
This commit is contained in:
mercyblitz 2019-03-07 16:29:31 +08:00
parent 514fef53f5
commit e48863640a
17 changed files with 448 additions and 347 deletions

View File

@ -20,12 +20,15 @@ import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.config.spring.util.PropertySourcesUtils; import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources; 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.DubboGenericServiceExecutionContextFactory;
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; 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.PathVariableServiceParameterResolver;
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver; 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.RequestHeaderServiceParameterResolver;
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@ -67,6 +70,11 @@ public class DubboServiceAutoConfiguration {
static class ParameterResolversConfiguration { 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 * Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459

View File

@ -30,16 +30,16 @@ import java.util.Set;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class ServiceRestMetadata { public class ServiceRestMetadata {
private String name; private String url;
private Set<RestMethodMetadata> meta; private Set<RestMethodMetadata> meta;
public String getName() { public String getUrl() {
return name; return url;
} }
public void setName(String name) { public void setUrl(String url) {
this.name = name; this.url = url;
} }
public Set<RestMethodMetadata> getMeta() { public Set<RestMethodMetadata> getMeta() {
@ -55,12 +55,12 @@ public class ServiceRestMetadata {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof ServiceRestMetadata)) return false; if (!(o instanceof ServiceRestMetadata)) return false;
ServiceRestMetadata that = (ServiceRestMetadata) o; ServiceRestMetadata that = (ServiceRestMetadata) o;
return Objects.equals(name, that.name) && return Objects.equals(url, that.url) &&
Objects.equals(meta, that.meta); Objects.equals(meta, that.meta);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(name, meta); return Objects.hash(url, meta);
} }
} }

View File

@ -28,7 +28,6 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -115,10 +114,10 @@ public class DubboServiceBeanMetadataResolver implements BeanClassLoaderAware, S
List<URL> urls = serviceBean.getExportedUrls(); List<URL> urls = serviceBean.getExportedUrls();
urls.stream() urls.stream()
.map(SpringCloudRegistry::getServiceName) .map(URL::toString)
.forEach(serviceName -> { .forEach(url -> {
ServiceRestMetadata metadata = new ServiceRestMetadata(); ServiceRestMetadata metadata = new ServiceRestMetadata();
metadata.setName(serviceName); metadata.setUrl(url);
metadata.setMeta(methodRestMetadata); metadata.setMeta(methodRestMetadata);
serviceRestMetadata.add(metadata); serviceRestMetadata.add(metadata);
}); });

View File

@ -18,10 +18,11 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL; 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.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -29,20 +30,49 @@ import java.util.LinkedHashMap;
* Abstract {@link RegistrationFactory} implementation * Abstract {@link RegistrationFactory} implementation
* <p> * <p>
* *
* @param <T> The subclass of {@link Registration} * @param <R> The subclass of {@link Registration}
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/ */
public abstract class AbstractRegistrationFactory<T extends Registration> implements RegistrationFactory<T> { public abstract class AbstractRegistrationFactory<R extends Registration> implements RegistrationFactory<R> {
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 // Append default category if absent
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category); URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol()); 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()); 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())); serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
return serviceInstance; return serviceInstance;
} }
protected String createServiceId(URL url, ConfigurableApplicationContext applicationContext) {
DubboRegistryServiceIdHandler handler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
return handler.createServiceId(url);
}
} }

View File

@ -17,8 +17,9 @@
package org.springframework.cloud.alibaba.dubbo.registry; package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URL;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
/** /**
* Default {@link RegistrationFactory} * Default {@link RegistrationFactory}
@ -28,7 +29,7 @@ import org.springframework.context.ApplicationContext;
public class DefaultRegistrationFactory extends AbstractRegistrationFactory<Registration> { public class DefaultRegistrationFactory extends AbstractRegistrationFactory<Registration> {
@Override @Override
public Registration create(String serviceName, URL url, ApplicationContext applicationContext) { protected Registration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
return new DelegatingRegistration(createServiceInstance(serviceName, url)); return new DelegatingRegistration(serviceInstance);
} }
} }

View File

@ -18,24 +18,23 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URL;
import org.springframework.cloud.client.serviceregistry.Registration; 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} * {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
* *
* @param <T> The subclass of {@link Registration} * @param <R> The subclass of {@link Registration}
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/ */
public interface RegistrationFactory<T extends Registration> { public interface RegistrationFactory<R extends Registration> {
/** /**
* 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 {@link URL}
* @param url The Dubbo's URL * @param applicationContext {@link ConfigurableApplicationContext}
* @param applicationContext {@link ApplicationContext} * @return a instance of {@link R}, if null, it indicates the registration will not be executed.
* @return a instance of {@link T}
*/ */
T create(String serviceName, URL url, ApplicationContext applicationContext); R create(URL url, ConfigurableApplicationContext applicationContext);
} }

View File

@ -18,44 +18,35 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.RegistryFactory; import org.apache.dubbo.registry.RegistryFactory;
import org.apache.dubbo.registry.support.FailbackRegistry; import org.apache.dubbo.registry.support.FailbackRegistry;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.ResolvableType;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Map;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY; import static java.util.Collections.singletonList;
import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY; import static org.apache.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY; import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY; import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
import static java.lang.Long.getLong; import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static org.apache.dubbo.common.Constants.ROUTERS_CATEGORY;
import static org.springframework.beans.BeanUtils.instantiateClass; import static org.apache.dubbo.common.Constants.SIDE_KEY;
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" * 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 { 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 * All supported categories
*/ */
private static final String[] ALL_SUPPORTED_CATEGORIES = of( public static final String[] ALL_SUPPORTED_CATEGORIES = of(
PROVIDERS_CATEGORY, PROVIDERS_CATEGORY,
CONSUMERS_CATEGORY, CONSUMERS_CATEGORY,
ROUTERS_CATEGORY, ROUTERS_CATEGORY,
CONFIGURATORS_CATEGORY CONFIGURATORS_CATEGORY
); );
private static final int CATEGORY_INDEX = 0; private final Logger logger = LoggerFactory.getLogger(getClass());
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 = "*";
/** /**
* The interval in second of lookup service names(only for Dubbo-OPS) * 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;
/** private final long registeredServicesLookupInterval;
* The interval in second of lookup regigered service instances
*/
private static final long REGISTERED_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.registered.services.lookup.interval", 300);
/**
* The {@link ScheduledExecutorService Scheduler} to lookup the registered services
*/
private static final ScheduledExecutorService registeredServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-registered-services-lookup-"));
/**
* The {@link ScheduledExecutorService Scheduler} to lookup all services (only for Dubbo-OPS)
*/
private static volatile ScheduledExecutorService allServicesLookupScheduler;
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* The separator for service name
*/
private static final String SERVICE_NAME_SEPARATOR = ":";
private final ApplicationContext applicationContext;
private final ServiceRegistry<Registration> serviceRegistry; private final ServiceRegistry<Registration> serviceRegistry;
private final DiscoveryClient discoveryClient;
private final RegistrationFactory registrationFactory; private final RegistrationFactory registrationFactory;
public SpringCloudRegistry(URL url, ApplicationContext applicationContext) { private final DiscoveryClient discoveryClient;
private final DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler;
private final ScheduledExecutorService servicesLookupScheduler;
private final ConfigurableApplicationContext applicationContext;
public SpringCloudRegistry(URL url,
ServiceRegistry<Registration> serviceRegistry,
RegistrationFactory registrationFactory,
DiscoveryClient discoveryClient,
ScheduledExecutorService servicesLookupScheduler,
ConfigurableApplicationContext applicationContext) {
super(url); 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.applicationContext = applicationContext;
this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class); this.servicesLookupScheduler = servicesLookupScheduler;
this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
applicationContext.getClassLoader();
} }
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry, protected boolean shouldRegister(Registration registration) {
ClassLoader classLoader) { Map<String, String> metadata = registration.getMetadata();
RegistrationFactory registrationFactory = null; String side = metadata.get(SIDE_KEY);
List<String> factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader); return PROVIDER_SIDE.equals(side); // Only register the Provider.
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);
}
@Override @Override
public void doRegister(URL url) { public void doRegister(URL url) {
final String serviceName = getServiceName(url); final Registration registration = createRegistration(url);
final Registration registration = createRegistration(serviceName, url); if (shouldRegister(registration)) {
serviceRegistry.register(registration); serviceRegistry.register(registration);
}
} }
@Override @Override
public void doUnregister(URL url) { public void doUnregister(URL url) {
final String serviceName = getServiceName(url); final Registration registration = createRegistration(url);
final Registration registration = createRegistration(serviceName, url); if (shouldRegister(registration)) {
this.serviceRegistry.deregister(registration); this.serviceRegistry.deregister(registration);
}
} }
@Override @Override
public void doSubscribe(URL url, NotifyListener listener) { public void doSubscribe(URL url, NotifyListener listener) {
List<String> serviceNames = getServiceNames(url, listener); List<String> serviceNames = getServiceNames(url, listener);
doSubscribe(url, listener, serviceNames); doSubscribe(url, listener, serviceNames);
this.registeredServicesLookupScheduler.scheduleAtFixedRate(new Runnable() { this.servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
doSubscribe(url, listener, serviceNames); doSubscribe(url, listener, serviceNames);
} }
}, REGISTERED_SERVICES_LOOKUP_INTERVAL, REGISTERED_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS); }, registeredServicesLookupInterval, registeredServicesLookupInterval, TimeUnit.SECONDS);
} }
@Override @Override
@ -234,136 +152,34 @@ public class SpringCloudRegistry extends FailbackRegistry {
if (isAdminProtocol(url)) { if (isAdminProtocol(url)) {
shutdownServiceNamesLookup(); shutdownServiceNamesLookup();
} }
// if (registeredServicesLookupScheduler != null) {
// registeredServicesLookupScheduler.shutdown();
// }
} }
@Override @Override
public boolean isAvailable() { public boolean isAvailable() {
return false; return !discoveryClient.getServices().isEmpty();
} }
private void shutdownServiceNamesLookup() { private void shutdownServiceNamesLookup() {
if (allServicesLookupScheduler != null) { if (servicesLookupScheduler != null) {
allServicesLookupScheduler.shutdown(); servicesLookupScheduler.shutdown();
} }
} }
private Registration createRegistration(String serviceName, URL url) { private Registration createRegistration(URL url) {
return registrationFactory.create(serviceName, url, applicationContext); return registrationFactory.create(url, applicationContext);
} }
public static String getServiceName(URL url) { private void filterServiceNames(List<String> serviceNames) {
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 void filterServiceNames(List<String> 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);
filter(serviceNames, new Filter<String>() { filter(serviceNames, new Filter<String>() {
@Override @Override
public boolean accept(String serviceName) { public boolean accept(String serviceName) {
// split service name to segments return dubboRegistryServiceIdHandler.supports(serviceName);
// (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;
} }
}); });
} }
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<String> getAllServiceNames() { private List<String> getAllServiceNames() {
return discoveryClient.getServices(); return new LinkedList<>(discoveryClient.getServices());
} }
/** /**
@ -378,7 +194,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
initAllServicesLookupScheduler(url, listener); initAllServicesLookupScheduler(url, listener);
return getServiceNamesForOps(url); return getServiceNamesForOps(url);
} else { } 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) { private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
if (allServicesLookupScheduler == null) { servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
allServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-all-services-lookup-")); @Override
allServicesLookupScheduler.scheduleAtFixedRate(new Runnable() { public void run() {
@Override List<String> serviceNames = getAllServiceNames();
public void run() { filterServiceNames(serviceNames);
List<String> serviceNames = getAllServiceNames(); doSubscribe(url, listener, serviceNames);
filter(serviceNames, new Filter<String>() { }
@Override }, allServicesLookupInterval, allServicesLookupInterval, TimeUnit.SECONDS);
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);
}
} }
private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) { private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) {
@ -421,16 +221,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
} }
} }
private List<String> doGetServiceNames(URL url) {
String[] categories = getCategories(url);
List<String> serviceNames = new ArrayList<String>(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. * Notify the Healthy {@link ServiceInstance service instance} to subscriber.
* *
@ -487,7 +277,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
*/ */
private List<String> getServiceNamesForOps(URL url) { private List<String> getServiceNamesForOps(URL url) {
List<String> serviceNames = getAllServiceNames(); List<String> serviceNames = getAllServiceNames();
filterServiceNames(serviceNames, url); filterServiceNames(serviceNames);
return serviceNames; return serviceNames;
} }
@ -508,7 +298,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
/** /**
* A filter * A filter
*/ */
private interface Filter<T> { public interface Filter<T> {
/** /**
* Tests whether or not the specified data should be accepted. * Tests whether or not the specified data should be accepted.

View File

@ -17,9 +17,28 @@
package org.springframework.cloud.alibaba.dubbo.registry; package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory; 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" * 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 { 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<Registration> 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 @Override
public Registry getRegistry(URL url) { 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; SpringCloudRegistryFactory.applicationContext = applicationContext;
} }
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry,
ClassLoader classLoader) {
RegistrationFactory registrationFactory = null;
List<String> 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);
}
} }

View File

@ -23,7 +23,7 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance; import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration; import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration; import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
/** /**
* Zookeeper {@link RegistrationFactory} * Zookeeper {@link RegistrationFactory}
@ -33,10 +33,7 @@ import org.springframework.context.ApplicationContext;
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> { public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> {
@Override @Override
public ZookeeperRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { protected ZookeeperRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(), ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
serviceInstance.getServiceId(), serviceInstance.getMetadata()); serviceInstance.getServiceId(), serviceInstance.getMetadata());

View File

@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
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 <code>true</code>, or <code>false</code>
*/
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();
}

View File

@ -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}
* <p>
* The service ID pattern is "${category}:${interface}:${version}:${group}"
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
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);
}
}
}

View File

@ -24,7 +24,7 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils; import org.springframework.cloud.consul.discovery.ConsulServerUtils;
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -40,9 +40,7 @@ import java.util.Set;
public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> { public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> {
@Override @Override
public ConsulRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { protected ConsulRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
Map<String, String> metadata = getMetadata(serviceInstance); Map<String, String> metadata = getMetadata(serviceInstance);
List<String> tags = createTags(metadata); List<String> tags = createTags(metadata);

View File

@ -27,7 +27,7 @@ import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig; import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
/** /**
* {@link EurekaRegistration} Factory * {@link EurekaRegistration} Factory
@ -37,8 +37,7 @@ import org.springframework.context.ApplicationContext;
public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> { public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> {
@Override @Override
public EurekaRegistration create(String serviceName, URL url, ApplicationContext applicationContext) { protected EurekaRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class); CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class); ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class); EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);

View File

@ -16,6 +16,7 @@
*/ */
package org.springframework.cloud.alibaba.dubbo.service; package org.springframework.cloud.alibaba.dubbo.service;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -30,12 +31,10 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import static com.alibaba.dubbo.common.Constants.DEFAULT_CLUSTER; import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER;
import static com.alibaba.dubbo.common.Constants.DEFAULT_PROTOCOL; import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup; import static org.apache.dubbo.common.Constants.GROUP_KEY;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface; import static org.apache.dubbo.common.Constants.VERSION_KEY;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments;
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion;
/** /**
* Dubbo {@link GenericService} Factory * Dubbo {@link GenericService} Factory
@ -66,11 +65,11 @@ public class DubboGenericServiceFactory {
private ReferenceBean<GenericService> build(ServiceRestMetadata serviceRestMetadata, private ReferenceBean<GenericService> build(ServiceRestMetadata serviceRestMetadata,
DubboTransportedMetadata dubboTransportedMetadata) { DubboTransportedMetadata dubboTransportedMetadata) {
String dubboServiceName = serviceRestMetadata.getName(); String urlValue = serviceRestMetadata.getUrl();
String[] segments = getServiceSegments(dubboServiceName); URL url = URL.valueOf(urlValue);
String interfaceName = getServiceInterface(segments); String interfaceName = url.getServiceInterface();
String version = getServiceVersion(segments); String version = url.getParameter(VERSION_KEY);
String group = getServiceGroup(segments); String group = url.getParameter(GROUP_KEY);
String protocol = dubboTransportedMetadata.getProtocol(); String protocol = dubboTransportedMetadata.getProtocol();
String cluster = dubboTransportedMetadata.getCluster(); String cluster = dubboTransportedMetadata.getCluster();

View File

@ -9,7 +9,6 @@ org.springframework.context.ApplicationContextInitializer=\
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\ 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.netflix.eureka.EurekaRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\ org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory

View File

@ -1,5 +1,8 @@
dubbo: dubbo:
registry: 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: server:
port: 7070 port: 7070

View File

@ -10,7 +10,10 @@ dubbo:
port: 8081 port: 8081
server: netty server: netty
registry: 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: feign:
hystrix: hystrix: