Skip to content

Commit

Permalink
Polish apache#4330 : Add @com.alibaba.dubbo.config.annotation.Service…
Browse files Browse the repository at this point in the history
… support
  • Loading branch information
mercyblitz committed Jun 20, 2019
1 parent 21a0d1c commit d58405e
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 23 deletions.
6 changes: 6 additions & 0 deletions dubbo-config/dubbo-config-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-compatible</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
Expand Down Expand Up @@ -128,5 +133,6 @@
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
Expand All @@ -52,6 +53,7 @@
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
Expand All @@ -65,6 +67,7 @@
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.context.annotation.AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
import static org.springframework.util.ClassUtils.resolveClassName;

/**
Expand Down Expand Up @@ -132,6 +135,14 @@ private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegi

scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));

/**
* Add the compatibility for legacy Dubbo's @Service
*
* The issue : https://github.com/apache/dubbo/issues/4330
* @since 2.7.3
*/
scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class));

for (String packageToScan : packagesToScan) {

// Registers @Service Bean first
Expand Down Expand Up @@ -250,17 +261,22 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean

Class<?> beanClass = resolveClass(beanDefinitionHolder);

Service service = findAnnotation(beanClass, Service.class);
Annotation service = findServiceAnnotation(beanClass);

/**
* The {@link AnnotationAttributes} of @Service annotation
*/
AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false);

Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service);
Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, serviceAnnotationAttributes);

String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();

AbstractBeanDefinition serviceBeanDefinition =
buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);
buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName);

// ServiceBean Bean name
String beanName = generateServiceBeanName(service, interfaceClass);
String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass);

if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
registry.registerBeanDefinition(beanName, serviceBeanDefinition);
Expand All @@ -282,29 +298,52 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean

}


/**
* Find the {@link Annotation annotation} of @Service
*
* @param beanClass the {@link Class class} of Bean
* @return <code>null</code> if not found
* @since 2.7.3
*/
private Annotation findServiceAnnotation(Class<?> beanClass) {
Annotation service = findAnnotation(beanClass, Service.class);
if (service == null) {
service = findAnnotation(beanClass, com.alibaba.dubbo.config.annotation.Service.class);
}
return service;
}

/**
* Generates the bean name of {@link ServiceBean}
*
* @param service
* @param interfaceClass the class of interface annotated {@link Service}
* @param serviceAnnotationAttributes
* @param interfaceClass the class of interface annotated {@link Service}
* @return ServiceBean@interfaceClassName#annotatedServiceBeanName
* @since 2.5.9
* @since 2.7.3
*/
private String generateServiceBeanName(Service service, Class<?> interfaceClass) {
ServiceBeanNameBuilder builder = create(service, interfaceClass, environment);

private String generateServiceBeanName(AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass) {
ServiceBeanNameBuilder builder = create(interfaceClass, environment);
builder.group(serviceAnnotationAttributes.getString("group"));
builder.version(serviceAnnotationAttributes.getString("version"));
return builder.build();
}

private Class<?> resolveServiceInterfaceClass(Class<?> annotatedServiceBeanClass, Service service) {
/**
* @param annotatedServiceBeanClass
* @param serviceAnnotationAttributes
* @return
* @since 2.7.3
*/
private Class<?> resolveServiceInterfaceClass(Class<?> annotatedServiceBeanClass, AnnotationAttributes serviceAnnotationAttributes) {

Class<?> interfaceClass = service.interfaceClass();
Class<?> interfaceClass = serviceAnnotationAttributes.getClass("interfaceClass");

if (void.class.equals(interfaceClass)) {

interfaceClass = null;

String interfaceClassName = service.interfaceName();
String interfaceClassName = serviceAnnotationAttributes.getString("interfaceName");

if (StringUtils.hasText(interfaceClassName)) {
if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
Expand Down Expand Up @@ -361,7 +400,19 @@ private Set<String> resolvePackagesToScan(Set<String> packagesToScan) {
return resolvedPackagesToScan;
}

private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class<?> interfaceClass,
/**
* Build the {@link AbstractBeanDefinition Bean Definition}
*
* @param serviceAnnotation
* @param serviceAnnotationAttributes
* @param interfaceClass
* @param annotatedServiceBeanName
* @return
* @since 2.7.3
*/
private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation,
AnnotationAttributes serviceAnnotationAttributes,
Class<?> interfaceClass,
String annotatedServiceBeanName) {

BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
Expand All @@ -373,43 +424,43 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol",
"interface", "interfaceName", "parameters");

propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames));
propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotation, environment, ignoreAttributeNames));

// References "ref" property to annotated-@Service Bean
addPropertyReference(builder, "ref", annotatedServiceBeanName);
// Set interface
builder.addPropertyValue("interface", interfaceClass.getName());
// Convert parameters into map
builder.addPropertyValue("parameters", convertParameters(service.parameters()));
builder.addPropertyValue("parameters", convertParameters(serviceAnnotationAttributes.getStringArray("parameters")));

/**
* Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference
*/
String providerConfigBeanName = service.provider();
String providerConfigBeanName = serviceAnnotationAttributes.getString("provider");
if (StringUtils.hasText(providerConfigBeanName)) {
addPropertyReference(builder, "provider", providerConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference
*/
String monitorConfigBeanName = service.monitor();
String monitorConfigBeanName = serviceAnnotationAttributes.getString("monitor");
if (StringUtils.hasText(monitorConfigBeanName)) {
addPropertyReference(builder, "monitor", monitorConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference
*/
String applicationConfigBeanName = service.application();
String applicationConfigBeanName = serviceAnnotationAttributes.getString("application");
if (StringUtils.hasText(applicationConfigBeanName)) {
addPropertyReference(builder, "application", applicationConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference
*/
String moduleConfigBeanName = service.module();
String moduleConfigBeanName = serviceAnnotationAttributes.getString("module");
if (StringUtils.hasText(moduleConfigBeanName)) {
addPropertyReference(builder, "module", moduleConfigBeanName);
}
Expand All @@ -418,7 +469,7 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class
/**
* Add {@link org.apache.dubbo.config.RegistryConfig} Bean reference
*/
String[] registryConfigBeanNames = service.registry();
String[] registryConfigBeanNames = serviceAnnotationAttributes.getStringArray("registry");

List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames);

Expand All @@ -429,7 +480,7 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class
/**
* Add {@link org.apache.dubbo.config.ProtocolConfig} Bean reference
*/
String[] protocolConfigBeanNames = service.protocol();
String[] protocolConfigBeanNames = serviceAnnotationAttributes.getStringArray("protocol");

List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
*/
package org.apache.dubbo.config.spring.context.annotation.provider;

import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.api.HelloService;

import com.alibaba.dubbo.config.annotation.Service;

/**
* {@link HelloService} Implementation just annotating Dubbo's {@link Service}
*
Expand Down

0 comments on commit d58405e

Please sign in to comment.