diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java index 1714b864..2716510b 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java @@ -17,21 +17,29 @@ package org.springframework.cloud.alibaba.dubbo.autoconfigure; import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.spring.ServiceBean; +import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent; import feign.Contract; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.cloud.alibaba.dubbo.metadata.DubboProtocolConfigSupplier; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboServiceBeanMetadataResolver; import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; +import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceExporter; import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceProxy; import org.springframework.cloud.alibaba.dubbo.service.PublishingDubboMetadataConfigService; import org.springframework.cloud.alibaba.dubbo.util.JSONUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; import java.util.Collection; import java.util.function.Supplier; @@ -42,9 +50,21 @@ import java.util.function.Supplier; * @author Mercy */ @Configuration -@Import({DubboServiceMetadataRepository.class, PublishingDubboMetadataConfigService.class, JSONUtils.class}) +@Import({DubboServiceMetadataRepository.class, + PublishingDubboMetadataConfigService.class, + DubboMetadataConfigServiceExporter.class, + JSONUtils.class}) public class DubboMetadataAutoConfiguration { + @Autowired + private PublishingDubboMetadataConfigService dubboMetadataConfigService; + + @Autowired + private MetadataResolver metadataResolver; + + @Autowired + private DubboMetadataConfigServiceExporter dubboMetadataConfigServiceExporter; + @Bean @ConditionalOnMissingBean public MetadataResolver metadataJsonResolver(ObjectProvider contract) { @@ -61,4 +81,31 @@ public class DubboMetadataAutoConfiguration { public DubboMetadataConfigServiceProxy dubboMetadataConfigServiceProxy(DubboGenericServiceFactory factory) { return new DubboMetadataConfigServiceProxy(factory); } + + // Event-Handling + + @EventListener(ServiceBeanExportedEvent.class) + public void onServiceBeanExported(ServiceBeanExportedEvent event) { + ServiceBean serviceBean = event.getServiceBean(); + publishServiceRestMetadata(serviceBean); + } + + private void publishServiceRestMetadata(ServiceBean serviceBean) { + dubboMetadataConfigService.publishServiceRestMetadata(metadataResolver.resolveServiceRestMetadata(serviceBean)); + } + + @EventListener(ApplicationReadyEvent.class) + public void onApplicationReady() { + dubboMetadataConfigServiceExporter.export(); + } + + @EventListener(ApplicationFailedEvent.class) + public void onApplicationFailed() { + dubboMetadataConfigServiceExporter.unexport(); + } + + @EventListener(ContextClosedEvent.class) + public void onContextClosed() { + dubboMetadataConfigServiceExporter.unexport(); + } } \ No newline at end of file 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 c06108ed..c4abb94e 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 @@ -21,16 +21,12 @@ 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.ServiceRegistryAspect; -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; @@ -72,17 +68,6 @@ public class DubboServiceAutoConfiguration { static class ParameterResolversConfiguration { } - @Bean - public ServiceRegistryAspect serviceRegistryAspect() { - return new ServiceRegistryAspect(); - } - - @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/autoconfigure/DubboMetadataEventHandlingAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java similarity index 59% rename from spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataEventHandlingAutoConfiguration.java rename to spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index c4823169..e6c2432a 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataEventHandlingAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -17,35 +17,27 @@ package org.springframework.cloud.alibaba.dubbo.autoconfigure; import org.apache.dubbo.common.URL; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.ProtocolConfig; -import org.apache.dubbo.config.ServiceConfig; -import org.apache.dubbo.config.spring.ServiceBean; import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent; import com.ecwid.consul.v1.agent.model.NewService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; -import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver; +import org.springframework.cloud.alibaba.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent; -import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigService; -import org.springframework.cloud.alibaba.dubbo.service.PublishingDubboMetadataConfigService; +import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceExporter; import org.springframework.cloud.alibaba.dubbo.util.JSONUtils; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.annotation.Import; import org.springframework.context.event.EventListener; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -53,19 +45,19 @@ import org.springframework.util.StringUtils; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import java.util.stream.Collectors; import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.DUBBO_URLS_METADATA_PROPERTY_NAME; /** - * The Auto-Configuration class for Dubbo metadata {@link EventListener event handling}. + * Dubbo Service Registration Auto-{@link Configuration} * * @author Mercy */ -@AutoConfigureAfter(value = {DubboMetadataAutoConfiguration.class}) @Configuration -public class DubboMetadataEventHandlingAutoConfiguration { +@Import({DubboServiceRegistrationEventPublishingAspect.class}) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) +public class DubboServiceRegistrationAutoConfiguration { private static final String CONSUL_REGISTRATION_CLASS_NAME = "org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration"; @@ -76,44 +68,18 @@ public class DubboMetadataEventHandlingAutoConfiguration { private final Logger logger = LoggerFactory.getLogger(getClass()); @Autowired - private MetadataResolver metadataResolver; - - @Autowired - private PublishingDubboMetadataConfigService dubboMetadataConfigService; - - @Autowired - private ApplicationConfig applicationConfig; - - @Autowired - private Supplier protocolConfigSupplier; - - @Autowired - private ConfigurableApplicationContext context; + private ServiceRegistry serviceRegistry; @Autowired private DubboServiceMetadataRepository dubboServiceMetadataRepository; @Autowired - private JSONUtils jsonUtils; - - @Value("${spring.application.name:application}") - private String currentApplicationName; + private DubboMetadataConfigServiceExporter dubboMetadataConfigServiceExporter; @Autowired - private ServiceRegistry serviceRegistry; + private JSONUtils jsonUtils; - private volatile Registration registration; - - /** - * The ServiceConfig of DubboMetadataConfigService to be exported, can be nullable. - */ - private ServiceConfig serviceConfig; - - @EventListener(ServiceBeanExportedEvent.class) - public void onServiceBeanExported(ServiceBeanExportedEvent event) { - ServiceBean serviceBean = event.getServiceBean(); - publishServiceRestMetadata(serviceBean); - } + private Registration registration; @ConditionalOnClass(name = EUREKA_REGISTRATION_CLASS_NAME) @Bean @@ -131,20 +97,15 @@ public class DubboMetadataEventHandlingAutoConfiguration { serviceRegistry.register(registration); } - @EventListener(ApplicationFailedEvent.class) - public void onApplicationFailed() { - unexportDubboMetadataConfigService(); - } - @EventListener(ContextClosedEvent.class) - public void onContextClosed() { - unexportDubboMetadataConfigService(); - } + // Event-Handling @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { + + dubboMetadataConfigServiceExporter.export(); + Registration registration = event.getSource(); - exportDubboMetadataConfigService(); attachURLsIntoMetadata(registration); setRegistration(registration); } @@ -196,52 +157,4 @@ public class DubboMetadataEventHandlingAutoConfiguration { } return jsonUtils.toJSON(urls.stream().map(URL::toFullString).collect(Collectors.toList())); } - - private void publishServiceRestMetadata(ServiceBean serviceBean) { - dubboMetadataConfigService.publishServiceRestMetadata(metadataResolver.resolveServiceRestMetadata(serviceBean)); - } - - private void exportDubboMetadataConfigService() { - - if (serviceConfig != null && serviceConfig.isExported()) { - return; - } - - if (StringUtils.isEmpty(dubboMetadataConfigService.getServiceRestMetadata())) { - // If there is no REST metadata, DubboMetadataConfigService will not be exported. - if (logger.isInfoEnabled()) { - logger.info("There is no REST metadata, the Dubbo service[{}] will not be exported.", - dubboMetadataConfigService.getClass().getName()); - } - return; - } - - serviceConfig = new ServiceConfig<>(); - - serviceConfig.setInterface(DubboMetadataConfigService.class); - // Use current Spring application name as the Dubbo Service version - serviceConfig.setVersion(currentApplicationName); - serviceConfig.setRef(dubboMetadataConfigService); - serviceConfig.setApplication(applicationConfig); - serviceConfig.setProtocol(protocolConfigSupplier.get()); - - serviceConfig.export(); - - if (logger.isInfoEnabled()) { - logger.info("The Dubbo service[{}] has been exported.", serviceConfig.toString()); - } - } - - private void unexportDubboMetadataConfigService() { - - if (serviceConfig == null || serviceConfig.isUnexported()) { - return; - } - - serviceConfig.unexport(); - - if (logger.isInfoEnabled()) { - logger.info("The Dubbo service[{}] has been unexported.", serviceConfig.toString()); - } - } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/ServiceRegistryAspect.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java similarity index 91% rename from spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/ServiceRegistryAspect.java rename to spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java index 72ac16b0..ca05d837 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/ServiceRegistryAspect.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java @@ -27,12 +27,14 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; /** - * {@link ServiceRegistry} Aspect + * Dubbo Service Registration Event-Publishing Aspect * * @author Mercy + * @see ServiceInstancePreRegisteredEvent + * @see ServiceInstanceRegisteredEvent */ @Aspect -public class ServiceRegistryAspect implements ApplicationEventPublisherAware { +public class DubboServiceRegistrationEventPublishingAspect implements ApplicationEventPublisherAware { /** * The pointcut expression for {@link ServiceRegistry#register(Registration)} 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 deleted file mode 100644 index 15a35029..00000000 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 deleted file mode 100644 index caaa0706..00000000 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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/service/DubboMetadataConfigServiceExporter.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboMetadataConfigServiceExporter.java new file mode 100644 index 00000000..a47d1895 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboMetadataConfigServiceExporter.java @@ -0,0 +1,109 @@ +/* + * 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.service; + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.ServiceConfig; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.function.Supplier; + +/** + * {@link DubboMetadataConfigService} exporter + * + * @author Mercy + */ +@Component +public class DubboMetadataConfigServiceExporter { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationConfig applicationConfig; + + @Autowired + private PublishingDubboMetadataConfigService dubboMetadataConfigService; + + @Autowired + private Supplier protocolConfigSupplier; + + @Value("${spring.application.name:application}") + private String currentApplicationName; + + /** + * The ServiceConfig of DubboMetadataConfigService to be exported, can be nullable. + */ + private ServiceConfig serviceConfig; + + /** + * export {@link DubboMetadataConfigService} as Dubbo service + */ + public void export() { + + if (serviceConfig != null && serviceConfig.isExported()) { + return; + } + + if (StringUtils.isEmpty(dubboMetadataConfigService.getServiceRestMetadata())) { + // If there is no REST metadata, DubboMetadataConfigService will not be exported. + if (logger.isInfoEnabled()) { + logger.info("There is no REST metadata, the Dubbo service[{}] will not be exported.", + dubboMetadataConfigService.getClass().getName()); + } + return; + } + + serviceConfig = new ServiceConfig<>(); + + serviceConfig.setInterface(DubboMetadataConfigService.class); + // Use current Spring application name as the Dubbo Service version + serviceConfig.setVersion(currentApplicationName); + serviceConfig.setRef(dubboMetadataConfigService); + serviceConfig.setApplication(applicationConfig); + serviceConfig.setProtocol(protocolConfigSupplier.get()); + + serviceConfig.export(); + + if (logger.isInfoEnabled()) { + logger.info("The Dubbo service[{}] has been exported.", serviceConfig.toString()); + } + } + + + /** + * unexport {@link DubboMetadataConfigService} + */ + public void unexport() { + + if (serviceConfig == null || serviceConfig.isUnexported()) { + return; + } + + serviceConfig.unexport(); + + if (logger.isInfoEnabled()) { + logger.info("The Dubbo service[{}] has been unexported.", serviceConfig.toString()); + } + } +} 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 951a6362..572cee86 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 @@ -1,7 +1,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\ - org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataEventHandlingAutoConfiguration,\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration,\ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration