From 2d894f5fd3f1b17b90365eab9984a80fc67dc621 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Mon, 29 Apr 2019 20:27:43 +0800 Subject: [PATCH] Polish spring-cloud-incubator/spring-cloud-alibaba/#592 --- ...oServiceRegistrationAutoConfiguration.java | 14 ++++ ...gCloudRegistryConfigPropertyCondition.java | 70 +++++++++++++++++++ .../registry/SpringCloudRegistryFactory.java | 4 ++ .../service/DubboGenericServiceFactory.java | 23 ++++-- 4 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index 8c547b57..556874f6 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -16,6 +16,7 @@ */ package org.springframework.cloud.alibaba.dubbo.autoconfigure; +import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.spring.ServiceBean; import com.ecwid.consul.v1.agent.model.NewService; @@ -31,6 +32,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.alibaba.dubbo.autoconfigure.condition.MissingSpringCloudRegistryConfigPropertyCondition; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; import org.springframework.cloud.alibaba.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent; @@ -41,6 +43,8 @@ import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServic import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry; import org.springframework.context.SmartLifecycle; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.event.EventListener; @@ -51,6 +55,8 @@ import java.util.Map; import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_CONFIGURATION_CLASS_NAME; import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_AUTO_CONFIGURATION_CLASS_NAME; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistryFactory.ADDRESS; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistryFactory.PROTOCOL; import static org.springframework.util.ObjectUtils.isEmpty; /** @@ -87,6 +93,14 @@ public class DubboServiceRegistrationAutoConfiguration { @Autowired private DubboServiceMetadataRepository dubboServiceMetadataRepository; + @Bean + @Conditional(value = { + MissingSpringCloudRegistryConfigPropertyCondition.class + }) + public RegistryConfig defaultSpringCloudRegistryConfig() { + return new RegistryConfig(ADDRESS, PROTOCOL); + } + @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { Registration registration = event.getSource(); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java new file mode 100644 index 00000000..c1db9878 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/condition/MissingSpringCloudRegistryConfigPropertyCondition.java @@ -0,0 +1,70 @@ +/* + * 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.autoconfigure.condition; + +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.util.StringUtils; + +import java.util.Map; + +import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistryFactory.PROTOCOL; + +/** + * Missing {@link SpringCloudRegistry} Property {@link Condition} + * + * @see SpringCloudRegistry + * @see Condition + */ +public class MissingSpringCloudRegistryConfigPropertyCondition extends SpringBootCondition { + + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + ConfigurableEnvironment environment = (ConfigurableEnvironment) context.getEnvironment(); + + String protocol = environment.getProperty("dubbo.registry.protocol"); + + if (PROTOCOL.equals(protocol)) { + return ConditionOutcome.noMatch("'spring-cloud' protocol was found from 'dubbo.registry.protocol'"); + } + + String address = environment.getProperty("dubbo.registry.address"); + + if (StringUtils.startsWithIgnoreCase(address, PROTOCOL)) { + return ConditionOutcome.noMatch("'spring-cloud' protocol was found from 'dubbo.registry.address'"); + } + + Map properties = getSubProperties(environment, "dubbo.registries."); + + boolean found = properties.entrySet().stream().anyMatch(entry -> { + String key = entry.getKey(); + String value = String.valueOf(entry.getValue()); + return (key.endsWith(".address") && value.startsWith(PROTOCOL)) || + (key.endsWith(".protocol") && PROTOCOL.equals(value)); + + }); + + return found ? ConditionOutcome.noMatch("'spring-cloud' protocol was found in 'dubbo.registries.*'") : ConditionOutcome.match(); + } +} 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 36897cf6..da147555 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 @@ -41,6 +41,10 @@ import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; */ public class SpringCloudRegistryFactory implements RegistryFactory { + public static String PROTOCOL = "spring-cloud"; + + public static String ADDRESS = "localhost"; + private static String SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX = getProperty("dubbo.services.lookup.scheduler.thread.name.prefix ", "dubbo-services-lookup-"); 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 1198bd74..4cfa3a22 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 @@ -18,12 +18,15 @@ package org.springframework.cloud.alibaba.dubbo.service; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.rpc.service.GenericService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.cloud.alibaba.dubbo.metadata.DubboRestServiceMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; @@ -33,6 +36,7 @@ import org.springframework.validation.DataBinder; import javax.annotation.PreDestroy; import java.beans.PropertyEditorSupport; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @@ -54,6 +58,9 @@ public class DubboGenericServiceFactory { private final ConcurrentMap> cache = new ConcurrentHashMap<>(); + @Autowired + private ObjectProvider> registryConfigs; + public GenericService create(DubboRestServiceMetadata dubboServiceMetadata, Map dubboTranslatedAttributes) { @@ -85,18 +92,15 @@ public class DubboGenericServiceFactory { Integer key = Objects.hash(interfaceName, version, group, dubboTranslatedAttributes); - ReferenceBean referenceBean = cache.get(key); - - if (referenceBean == null) { - referenceBean = new ReferenceBean<>(); + return cache.computeIfAbsent(key, k -> { + ReferenceBean referenceBean = new ReferenceBean<>(); referenceBean.setGeneric(true); referenceBean.setInterface(interfaceName); referenceBean.setVersion(version); referenceBean.setGroup(group); bindReferenceBean(referenceBean, dubboTranslatedAttributes); - } - - return referenceBean; + return referenceBean; + }); } private void bindReferenceBean(ReferenceBean referenceBean, Map dubboTranslatedAttributes) { @@ -122,7 +126,12 @@ public class DubboGenericServiceFactory { } }); + // ignore "registries" field and then use RegistryConfig beans + dataBinder.setDisallowedFields("registries"); + dataBinder.bind(new MutablePropertyValues(dubboTranslatedAttributes)); + + registryConfigs.ifAvailable(referenceBean::setRegistries); } @PreDestroy