diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java index ba2da5b9fa..770694ec9b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java @@ -495,6 +495,11 @@ public interface AnnotationUtils { filteredAttributes.put(key, val); } }); + // remove void class, compatible with spring 3.x + Object interfaceClassValue = filteredAttributes.get("interfaceClass"); + if (interfaceClassValue instanceof String && StringUtils.isEquals((String) interfaceClassValue, "void")) { + filteredAttributes.remove("interfaceClass"); + } return filteredAttributes; } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java index 71591f7a5e..fe5af61ead 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java @@ -30,6 +30,7 @@ import org.apache.dubbo.config.spring.reference.ReferenceAttributes; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.config.spring.reference.ReferenceBeanManager; import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport; +import org.apache.dubbo.config.spring.util.SpringCompatUtils; import org.apache.dubbo.rpc.service.GenericService; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValue; @@ -40,7 +41,9 @@ import org.springframework.beans.factory.annotation.InjectionMetadata; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.AbstractBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; @@ -63,6 +66,7 @@ import java.util.concurrent.ConcurrentMap; import static com.alibaba.spring.util.AnnotationUtils.getAttribute; import static org.apache.dubbo.common.utils.AnnotationUtils.filterDefaultValues; +import static org.apache.dubbo.config.spring.util.SpringCompatUtils.getPropertyValue; import static org.springframework.util.StringUtils.hasText; /** @@ -156,16 +160,24 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean } } - // This bean has bean register as BeanPostProcessor at org.apache.dubbo.config.spring.context.DubboInfraBeanRegisterPostProcessor.postProcessBeanFactory() - // so destroy this bean here, prevent register it as BeanPostProcessor again, avoid cause BeanPostProcessorChecker detection error - beanDefinitionRegistry.removeBeanDefinition(BEAN_NAME); + if (beanFactory instanceof AbstractBeanFactory) { + List beanPostProcessors = ((AbstractBeanFactory) beanFactory).getBeanPostProcessors(); + for (BeanPostProcessor beanPostProcessor : beanPostProcessors) { + if (beanPostProcessor == this) { + // This bean has bean register as BeanPostProcessor at org.apache.dubbo.config.spring.context.DubboInfraBeanRegisterPostProcessor.postProcessBeanFactory() + // so destroy this bean here, prevent register it as BeanPostProcessor again, avoid cause BeanPostProcessorChecker detection error + beanDefinitionRegistry.removeBeanDefinition(BEAN_NAME); + break; + } + } + } try { // this is an early event, it will be notified at org.springframework.context.support.AbstractApplicationContext.registerListeners() applicationContext.publishEvent(new DubboAnnotationInitedEvent(applicationContext)); } catch (Exception e) { // if spring version is less then 4.2, it does not support early application event - logger.error("publish early application event failed, please upgrade spring version to 4.2.x or later", e); + logger.warn("publish early application event failed, please upgrade spring version to 4.2.x or later: " + e); } } @@ -175,11 +187,8 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean private boolean isAnnotatedReferenceBean(BeanDefinition beanDefinition) { if (beanDefinition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDefinition; - if (annotatedBeanDefinition.getFactoryMethodMetadata() == null) { - return false; - } - String beanClassName = annotatedBeanDefinition.getFactoryMethodMetadata().getReturnTypeName(); - if (ReferenceBean.class.getName().equals(beanClassName)) { + String beanClassName = SpringCompatUtils.getFactoryMethodReturnType(annotatedBeanDefinition); + if (beanClassName != null && ReferenceBean.class.getName().equals(beanClassName)) { return true; } } @@ -205,10 +214,19 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean */ private void processReferenceAnnotatedBeanDefinition(String beanName, AnnotatedBeanDefinition beanDefinition) { + MethodMetadata factoryMethodMetadata = SpringCompatUtils.getFactoryMethodMetadata(beanDefinition); + // Extract beanClass from generic return type of java-config bean method: ReferenceBean // see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBeanFromMethod Class beanClass = getBeanFactory().getType(beanName); - MethodMetadata factoryMethodMetadata = beanDefinition.getFactoryMethodMetadata(); + if (beanClass == Object.class) { + beanClass = SpringCompatUtils.getGenericTypeOfReturnType(factoryMethodMetadata); + } + if (beanClass == Object.class) { + // bean class is invalid, ignore it + return; + } + if (beanClass == null) { String beanMethodSignature = factoryMethodMetadata.getDeclaringClassName()+"#"+factoryMethodMetadata.getMethodName()+"()"; throw new BeanCreationException("The ReferenceBean is missing necessary generic type, which returned by the @Bean method of Java-config class. " + @@ -239,6 +257,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean // get interface String interfaceName = (String) attributes.get(ReferenceAttributes.INTERFACE); + // check beanClass and reference interface class if (!StringUtils.isEquals(interfaceName, beanClass.getName()) && beanClass != GenericService.class) { String beanMethodSignature = factoryMethodMetadata.getDeclaringClassName()+"#"+factoryMethodMetadata.getMethodName()+"()"; @@ -466,7 +485,8 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean // see org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean() GenericBeanDefinition targetDefinition = new GenericBeanDefinition(); targetDefinition.setBeanClass(interfaceClass); - String id = (String) beanDefinition.getPropertyValues().get(ReferenceAttributes.ID); + String id = getPropertyValue(beanDefinition.getPropertyValues(), ReferenceAttributes.ID); + beanDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, id+"_decorated")); // signal object type since Spring 5.2 diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java index a23e8bee7d..9313315053 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java @@ -29,10 +29,12 @@ import org.apache.dubbo.config.spring.ServiceBean; import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner; import org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser; import org.apache.dubbo.config.spring.util.DubboAnnotationUtils; +import org.apache.dubbo.config.spring.util.SpringCompatUtils; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; @@ -77,11 +79,11 @@ import java.util.Set; import static com.alibaba.spring.util.ObjectUtils.of; import static java.util.Arrays.asList; import static org.apache.dubbo.common.utils.AnnotationUtils.filterDefaultValues; +import static org.apache.dubbo.common.utils.AnnotationUtils.findAnnotation; import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create; import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName; 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.AnnotatedElementUtils.findMergedAnnotation; import static org.springframework.util.ClassUtils.resolveClassName; /** @@ -94,7 +96,7 @@ import static org.springframework.util.ClassUtils.resolveClassName; * @since 2.7.7 */ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, - ResourceLoaderAware, BeanClassLoaderAware, ApplicationContextAware { + ResourceLoaderAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean { public static final String BEAN_NAME = "dubboServiceAnnotationPostProcessor"; @@ -111,6 +113,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos protected final Set packagesToScan; + private Set resolvedPackagesToScan; private Environment environment; @@ -122,6 +125,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos private ServicePackagesHolder servicePackagesHolder; + private volatile boolean scaned = false; public ServiceAnnotationPostProcessor(String... packagesToScan) { this(asList(packagesToScan)); @@ -135,20 +139,39 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos this.packagesToScan = packagesToScan; } + @Override + public void afterPropertiesSet() throws Exception { + this.resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); + } + @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { this.registry = registry; + scanServiceBeans(resolvedPackagesToScan, registry); + } - Set resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + if (this.registry == null) { + // In spring 3.x, may be not call postProcessBeanDefinitionRegistry() + this.registry = (BeanDefinitionRegistry) beanFactory; + } - if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) { - scanServiceBeans(resolvedPackagesToScan, registry); - } else { - if (logger.isWarnEnabled()) { - logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!"); + // scan bean definitions + String[] beanNames = beanFactory.getBeanDefinitionNames(); + for (String beanName : beanNames) { + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + Map annotationAttributes = getServiceAnnotationAttributes(beanDefinition); + if (annotationAttributes != null) { + // process @DubboService at java-config @bean method + processAnnotatedBeanDefinition(beanName, (AnnotatedBeanDefinition) beanDefinition, annotationAttributes); } } + if (!scaned) { + // In spring 3.x, may be not call postProcessBeanDefinitionRegistry(), so scan service class here + scanServiceBeans(resolvedPackagesToScan, registry); + } } /** @@ -159,6 +182,14 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos */ private void scanServiceBeans(Set packagesToScan, BeanDefinitionRegistry registry) { + scaned = true; + if (CollectionUtils.isEmpty(packagesToScan)) { + if (logger.isWarnEnabled()) { + logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!"); + } + return; + } + DubboClassPathBeanDefinitionScanner scanner = new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader); @@ -325,7 +356,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos private Annotation findServiceAnnotation(Class beanClass) { return serviceAnnotationTypes .stream() - .map(annotationType -> findMergedAnnotation(beanClass, annotationType)) + .map(annotationType -> findAnnotation(beanClass, annotationType)) .filter(Objects::nonNull) .findFirst() .orElse(null); @@ -482,19 +513,6 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos builder.addPropertyValue(propertyName, resolvedBeanName); } - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - String[] beanNames = beanFactory.getBeanDefinitionNames(); - for (String beanName : beanNames) { - BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); - Map annotationAttributes = getServiceAnnotationAttributes(beanDefinition); - if (annotationAttributes != null) { - // process @DubboService at java-config @bean method - processAnnotatedBeanDefinition(beanName, (AnnotatedBeanDefinition) beanDefinition, annotationAttributes); - } - } - } - /** * Get dubbo service annotation class at java-config @bean method * @return return service annotation attributes map if found, or return null if not found. @@ -502,7 +520,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos private Map getServiceAnnotationAttributes(BeanDefinition beanDefinition) { if (beanDefinition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDefinition; - MethodMetadata factoryMethodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata(); + MethodMetadata factoryMethodMetadata = SpringCompatUtils.getFactoryMethodMetadata(annotatedBeanDefinition); if (factoryMethodMetadata != null) { // try all dubbo service annotation types for (Class annotationType : serviceAnnotationTypes) { @@ -542,7 +560,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos Map serviceAnnotationAttributes = new LinkedHashMap<>(attributes); // get bean class from return type - String returnTypeName = refServiceBeanDefinition.getFactoryMethodMetadata().getReturnTypeName(); + String returnTypeName = SpringCompatUtils.getFactoryMethodReturnType(refServiceBeanDefinition); Class beanClass = resolveClassName(returnTypeName, classLoader); String serviceInterface = resolveInterfaceName(serviceAnnotationAttributes, beanClass); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java index 90d06805cb..ffb1335eaa 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java @@ -54,11 +54,17 @@ public class DubboBootstrapApplicationListener implements ApplicationListener, A private final DubboBootstrap dubboBootstrap; private ApplicationContext applicationContext; + private boolean shouldInitConfigBeans; public DubboBootstrapApplicationListener() { this.dubboBootstrap = initBootstrap(); } + public DubboBootstrapApplicationListener(boolean shouldInitConfigBeans) { + this.dubboBootstrap = initBootstrap(); + this.shouldInitConfigBeans = shouldInitConfigBeans; + } + private DubboBootstrap initBootstrap() { DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance(); if (dubboBootstrap.getTakeoverMode() != BootstrapTakeoverMode.MANUAL) { @@ -142,7 +148,9 @@ public class DubboBootstrapApplicationListener implements ApplicationListener, A public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; - checkCallStackAndInit(); + if (shouldInitConfigBeans) { + checkCallStackAndInit(); + } } private void checkCallStackAndInit() { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java index 2c56100b8d..79529826d5 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java @@ -58,14 +58,17 @@ public class DubboInfraBeanRegisterPostProcessor implements BeanDefinitionRegist @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - // register ReferenceAnnotationBeanPostProcessor early before PropertySourcesPlaceholderConfigurer/PropertyPlaceholderConfigurer - // for processing early init ReferenceBean - ReferenceAnnotationBeanPostProcessor referenceAnnotationBeanPostProcessor = beanFactory.getBean( - ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class); - beanFactory.addBeanPostProcessor(referenceAnnotationBeanPostProcessor); + // In Spring 3.2.x, registry may be null because do not calling postProcessBeanDefinitionRegistry method before postProcessBeanFactory + if (registry != null) { + // register ReferenceAnnotationBeanPostProcessor early before PropertySourcesPlaceholderConfigurer/PropertyPlaceholderConfigurer + // for processing early init ReferenceBean + ReferenceAnnotationBeanPostProcessor referenceAnnotationBeanPostProcessor = beanFactory.getBean( + ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class); + beanFactory.addBeanPostProcessor(referenceAnnotationBeanPostProcessor); - // register PropertySourcesPlaceholderConfigurer bean if not exits - DubboBeanUtils.registerBeansIfNotExists(beanFactory, registry); + // register PropertySourcesPlaceholderConfigurer bean if not exits + DubboBeanUtils.registerPlaceholderConfigurerBeanIfNotExists(beanFactory, registry); + } // Initialize dubbo Environment before ConfigManager // Extract dubbo props from Spring env and put them to app config diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java index 7807efee95..25821d2b81 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java @@ -79,21 +79,43 @@ public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistra } private Set getPackagesToScan(AnnotationMetadata metadata) { - AnnotationAttributes attributes = AnnotationAttributes.fromMap( - metadata.getAnnotationAttributes(DubboComponentScan.class.getName())); - String[] basePackages = attributes.getStringArray("basePackages"); - Class[] basePackageClasses = attributes.getClassArray("basePackageClasses"); - String[] value = attributes.getStringArray("value"); - // Appends value array attributes - Set packagesToScan = new LinkedHashSet(Arrays.asList(value)); - packagesToScan.addAll(Arrays.asList(basePackages)); - for (Class basePackageClass : basePackageClasses) { - packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); + // get from @DubboComponentScan + Set packagesToScan = getPackagesToScan0(metadata, DubboComponentScan.class, "basePackages", "basePackageClasses"); + + // get from @EnableDubbo, compatible with spring 3.x + if (packagesToScan.isEmpty()) { + packagesToScan = getPackagesToScan0(metadata, EnableDubbo.class, "scanBasePackages", "scanBasePackageClasses"); } + if (packagesToScan.isEmpty()) { return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName())); } return packagesToScan; } + private Set getPackagesToScan0(AnnotationMetadata metadata, Class annotationClass, String basePackagesName, String basePackageClassesName) { + + AnnotationAttributes attributes = AnnotationAttributes.fromMap( + metadata.getAnnotationAttributes(annotationClass.getName())); + if (attributes == null) { + return Collections.emptySet(); + } + + Set packagesToScan = new LinkedHashSet<>(); + // basePackages + String[] basePackages = attributes.getStringArray(basePackagesName); + packagesToScan.addAll(Arrays.asList(basePackages)); + // basePackageClasses + Class[] basePackageClasses = attributes.getClassArray(basePackageClassesName); + for (Class basePackageClass : basePackageClasses) { + packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); + } + // value + if (attributes.containsKey("value")) { + String[] value = attributes.getStringArray("value"); + packagesToScan.addAll(Arrays.asList(value)); + } + return packagesToScan; + } + } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java index dfdb19afe2..066ea0b111 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java @@ -58,8 +58,16 @@ public class ReferenceBeanSupport { interfaceName = (String) attributes.get(ReferenceAttributes.INTERFACE_NAME); } if (interfaceName == null) { - Class clazz = (Class) attributes.get(ReferenceAttributes.INTERFACE_CLASS); - interfaceName = clazz != null ? clazz.getName() : null; + Object interfaceClassValue = attributes.get(ReferenceAttributes.INTERFACE_CLASS); + if (interfaceClassValue instanceof Class) { + interfaceName = ((Class) interfaceClassValue).getName(); + } else if (interfaceClassValue instanceof String) { + if (interfaceClassValue.equals("void")) { + attributes.remove(ReferenceAttributes.INTERFACE_CLASS); + } else { + interfaceName = (String) interfaceClassValue; + } + } } if (interfaceName == null && defaultInterfaceClass != GenericService.class) { interfaceName = defaultInterfaceClass.getName(); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java index 85f2034c96..a28b4976de 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java @@ -44,7 +44,6 @@ import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.core.env.Environment; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; @@ -61,6 +60,7 @@ import java.util.Set; import java.util.regex.Pattern; import static org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX; +import static org.apache.dubbo.config.spring.util.SpringCompatUtils.getPropertyValue; /** * AbstractBeanDefinitionParser @@ -76,6 +76,7 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { private static final String ONINVOKE = "oninvoke"; private static final String METHOD = "Method"; private static final String BEAN_NAME = "BEAN_NAME"; + private static boolean resolvePlaceholdersEnabled = true; private final Class beanClass; private static Map> beanPropsCache = new HashMap<>(); @@ -247,11 +248,10 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { String generic = resolveAttribute(element, ReferenceAttributes.GENERIC, parserContext); if (StringUtils.isBlank(generic) && consumerDefinition != null) { // get generic from consumerConfig - generic = (String) consumerDefinition.getPropertyValues().get(ReferenceAttributes.GENERIC); + generic = getPropertyValue(consumerDefinition.getPropertyValues(), ReferenceAttributes.GENERIC); } if (generic != null) { - Environment environment = parserContext.getReaderContext().getEnvironment(); - generic = environment.resolvePlaceholders(generic); + generic = resolvePlaceholders(generic, parserContext); beanDefinition.getPropertyValues().add(ReferenceAttributes.GENERIC, generic); } beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName); @@ -513,6 +513,13 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { } private static String resolvePlaceholders(String str, ParserContext parserContext) { - return parserContext.getReaderContext().getEnvironment().resolveRequiredPlaceholders(str); + if (resolvePlaceholdersEnabled) { + try { + return parserContext.getReaderContext().getEnvironment().resolveRequiredPlaceholders(str); + } catch (NoSuchMethodError e) { + resolvePlaceholdersEnabled = false; + } + } + return str; } } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java index 169af09141..72f2177b34 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java @@ -117,7 +117,7 @@ public interface DubboBeanUtils { } /** - * Register some beans later + * Register a placeholder configurer beans if not exists. * Call this method in BeanDefinitionRegistryPostProcessor, * in order to enable the registered BeanFactoryPostProcessor bean to be loaded and executed. * @see DubboInfraBeanRegisterPostProcessor @@ -125,7 +125,7 @@ public interface DubboBeanUtils { * @param beanFactory * @param registry */ - static void registerBeansIfNotExists(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) { + static void registerPlaceholderConfigurerBeanIfNotExists(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) { // Auto register a PropertyPlaceholderConfigurer bean to resolve placeholders with Spring Environment PropertySources // when loading dubbo xml config with @ImportResource if (!checkBeanExists(beanFactory, PropertySourcesPlaceholderConfigurer.class)) { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/SpringCompatUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/SpringCompatUtils.java new file mode 100644 index 0000000000..9faed82dbe --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/SpringCompatUtils.java @@ -0,0 +1,124 @@ +/* + * 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.apache.dubbo.config.spring.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.PropertyValues; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.core.type.MethodMetadata; +import org.springframework.core.type.StandardMethodMetadata; + +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Spring Compatibility Utils for spring 3.x/4.x/5.x + */ +public class SpringCompatUtils { + + private static volatile Boolean factoryMethodMetadataEnabled = null; + + private static final Log logger = LogFactory.getLog(SpringCompatUtils.class); + + public static T getPropertyValue(PropertyValues pvs, String propertyName) { + PropertyValue pv = pvs.getPropertyValue(propertyName); + return (pv != null ? (T) pv.getValue() : null); + } + + public static boolean isFactoryMethodMetadataEnabled() { + if (factoryMethodMetadataEnabled == null) { + try { + //check AnnotatedBeanDefinition.getFactoryMethodMetadata() since spring 4.1 + AnnotatedBeanDefinition.class.getMethod("getFactoryMethodMetadata"); + + // check MethodMetadata.getReturnTypeName() since spring 4.2 + MethodMetadata.class.getMethod("getReturnTypeName"); + + factoryMethodMetadataEnabled = true; + } catch (NoSuchMethodException e) { + factoryMethodMetadataEnabled = false; + } + } + return factoryMethodMetadataEnabled; + } + + public static String getFactoryMethodReturnType(AnnotatedBeanDefinition annotatedBeanDefinition) { + try { + if (isFactoryMethodMetadataEnabled()) { + MethodMetadata factoryMethodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata(); + return factoryMethodMetadata != null ? factoryMethodMetadata.getReturnTypeName() : null; + } else { + Object source = annotatedBeanDefinition.getSource(); + if (source instanceof StandardMethodMetadata) { + StandardMethodMetadata methodMetadata = (StandardMethodMetadata) source; + Method introspectedMethod = methodMetadata.getIntrospectedMethod(); + if (introspectedMethod != null) { + return introspectedMethod.getReturnType().getName(); + } + } + } + } catch (Throwable e) { + if (logger.isInfoEnabled()) { + logger.info("get return type of AnnotatedBeanDefinition failed", e); + } + } + return null; + } + + public static MethodMetadata getFactoryMethodMetadata(AnnotatedBeanDefinition annotatedBeanDefinition) { + if (isFactoryMethodMetadataEnabled()) { + return annotatedBeanDefinition.getFactoryMethodMetadata(); + } else { + Object source = annotatedBeanDefinition.getSource(); + if (source instanceof StandardMethodMetadata) { + return (MethodMetadata) source; + } + return null; + } + } + + /** + * Get the generic type of return type of the method. + * + *
+     *  Source method:
+     *  ReferenceBean<DemoService> demoService()
+     *
+     *  Result: DemoService.class
+     * 
+ * + * @param factoryMethodMetadata + * @return + */ + public static Class getGenericTypeOfReturnType(MethodMetadata factoryMethodMetadata) { + if (factoryMethodMetadata instanceof StandardMethodMetadata) { + Method introspectedMethod = ((StandardMethodMetadata) factoryMethodMetadata).getIntrospectedMethod(); + Type returnType = introspectedMethod.getGenericReturnType(); + if (returnType instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) returnType; + Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; + if (actualTypeArgument instanceof Class) { + return (Class) actualTypeArgument; + } + } + } + return null; + } +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/ServiceBeanIdConflictProcessor.java b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/ServiceBeanIdConflictProcessor.java index b6bf04be38..77e062571f 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/ServiceBeanIdConflictProcessor.java +++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/ServiceBeanIdConflictProcessor.java @@ -19,6 +19,7 @@ package org.apache.dubbo.spring.boot.beans.factory.config; import org.apache.dubbo.config.ServiceConfig; import org.apache.dubbo.config.spring.ServiceBean; +import org.apache.dubbo.config.spring.reference.ReferenceAttributes; import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; @@ -33,6 +34,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import static org.apache.dubbo.config.spring.util.SpringCompatUtils.getPropertyValue; import static org.springframework.util.ClassUtils.getUserClass; import static org.springframework.util.ClassUtils.isAssignable; @@ -64,7 +66,8 @@ public class ServiceBeanIdConflictProcessor implements MergedBeanDefinitionPostP // Get raw bean type Class rawBeanType = getUserClass(beanType); if (isAssignable(ServiceConfig.class, rawBeanType)) { // ServiceConfig type or sub-type - String interfaceName = (String) beanDefinition.getPropertyValues().get("interface"); + String interfaceName = getPropertyValue(beanDefinition.getPropertyValues(), ReferenceAttributes.INTERFACE); + String mappedBeanName = interfaceNamesToBeanNames.putIfAbsent(interfaceName, beanName); // If mapped bean name exists and does not equal current bean name if (mappedBeanName != null && !mappedBeanName.equals(beanName)) { diff --git a/dubbo-test/dubbo-test-common/pom.xml b/dubbo-test/dubbo-test-common/pom.xml new file mode 100644 index 0000000000..9c529519ef --- /dev/null +++ b/dubbo-test/dubbo-test-common/pom.xml @@ -0,0 +1,61 @@ + + + + dubbo-test + org.apache.dubbo + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-test-common + + + 8 + 8 + true + + + + + org.apache.zookeeper + zookeeper + + + org.slf4j + slf4j-log4j12 + + + + + + org.apache.dubbo + dubbo-common + + + org.apache.dubbo + dubbo-rpc-api + + + org.apache.dubbo + dubbo-rpc-rest + + + diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/EmbeddedZooKeeper.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/EmbeddedZooKeeper.java new file mode 100644 index 0000000000..e91755a252 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/EmbeddedZooKeeper.java @@ -0,0 +1,244 @@ +/* + * 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.apache.dubbo.test.common; + +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + *

+ * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + *

+ * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + // clientPort = SocketUtils.findAvailableTcpPort(); + clientPort = NetUtils.getAvailablePort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + public int getPhase() { + return this.phase; + } + + /** + * {@inheritDoc} + */ + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + *

+ * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + + File.separator + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ErrorHandler.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ErrorHandler.java new file mode 100644 index 0000000000..b44ff13298 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ErrorHandler.java @@ -0,0 +1,27 @@ +/* + * 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.apache.dubbo.test.common; + +@FunctionalInterface +public interface ErrorHandler { + + /** + * Handle the given error, possibly rethrowing it as a fatal exception. + */ + void handleError(Throwable t); + +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/SysProps.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/SysProps.java new file mode 100644 index 0000000000..dac5edd9f9 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/SysProps.java @@ -0,0 +1,45 @@ +/* + * 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.apache.dubbo.test.common; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Use to set and clear System property + */ +public class SysProps { + + private static Map map = new LinkedHashMap(); + + public static void reset() { + map.clear(); + } + + public static void setProperty(String key, String value) { + map.put(key, value); + System.setProperty(key, value); + } + + public static void clear() { + for (String key : map.keySet()) { + System.clearProperty(key); + } + reset(); + } + +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ZooKeeperServer.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ZooKeeperServer.java new file mode 100644 index 0000000000..ba34753f51 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/ZooKeeperServer.java @@ -0,0 +1,43 @@ +/* + * 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.apache.dubbo.test.common; + +public class ZooKeeperServer { + + private static EmbeddedZooKeeper zookeeper1; + private static EmbeddedZooKeeper zookeeper2; + + public static void start() { + if (zookeeper1 == null) { + zookeeper1 = new EmbeddedZooKeeper(2181, true); + zookeeper1.start(); + } + if (zookeeper2 == null) { + zookeeper2 = new EmbeddedZooKeeper(2182, true); + zookeeper2.start(); + } + } + + public static void stop() { + if (zookeeper1 != null) { + zookeeper1.stop(); + } + if (zookeeper2 != null) { + zookeeper2.stop(); + } + } +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/DemoService.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/DemoService.java new file mode 100644 index 0000000000..9a5dfc155a --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/DemoService.java @@ -0,0 +1,27 @@ +/* + * 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.apache.dubbo.test.common.api; + +import java.util.concurrent.CompletableFuture; + +public interface DemoService { + + String sayHello(String name); + + CompletableFuture sayHelloAsync(String name); + +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/GreetingService.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/GreetingService.java new file mode 100644 index 0000000000..16df570e95 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/GreetingService.java @@ -0,0 +1,24 @@ +/* + * 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.apache.dubbo.test.common.api; + +/** + * + */ +public interface GreetingService { + String hello(); +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/RestDemoService.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/RestDemoService.java new file mode 100644 index 0000000000..809cd94d73 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/RestDemoService.java @@ -0,0 +1,45 @@ +/* + * 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.apache.dubbo.test.common.api; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + + +@Path("/demoService") +public interface RestDemoService { + @GET + @Path("/hello") + Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b); + + @GET + @Path("/error") + String error(); + + @POST + @Path("/say") + @Consumes({MediaType.TEXT_PLAIN}) + String sayHello(String name); + + @GET + @Path("/getRemoteApplicationName") + String getRemoteApplicationName(); +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/DemoServiceImpl.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/DemoServiceImpl.java new file mode 100644 index 0000000000..4b80d8b8b2 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/DemoServiceImpl.java @@ -0,0 +1,43 @@ +/* + * 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.apache.dubbo.test.common.impl; + +import org.apache.dubbo.config.annotation.DubboService; +import org.apache.dubbo.test.common.api.DemoService; + +import java.util.concurrent.CompletableFuture; + +@DubboService +public class DemoServiceImpl implements DemoService { + @Override + public String sayHello(String name) { + return "Hello " + name; + } + + @Override + public CompletableFuture sayHelloAsync(String name) { + CompletableFuture cf = CompletableFuture.supplyAsync(() -> { +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } + return "async result:" + name; + }); + return cf; + } +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/GreetingServiceImpl.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/GreetingServiceImpl.java new file mode 100644 index 0000000000..0ad249abf6 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/GreetingServiceImpl.java @@ -0,0 +1,30 @@ +/* + * 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.apache.dubbo.test.common.impl; + + +import org.apache.dubbo.test.common.api.GreetingService; + +/** + * + */ +public class GreetingServiceImpl implements GreetingService { + @Override + public String hello() { + return "Greetings!"; + } +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/RestDemoServiceImpl.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/RestDemoServiceImpl.java new file mode 100644 index 0000000000..c8633145ff --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/impl/RestDemoServiceImpl.java @@ -0,0 +1,58 @@ +/* + * 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.apache.dubbo.test.common.impl; + + +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.test.common.api.RestDemoService; + +import java.util.Map; + +public class RestDemoServiceImpl implements RestDemoService { + private static Map context; + private boolean called; + + public String sayHello(String name) { + called = true; + return "Hello, " + name; + } + + + public boolean isCalled() { + return called; + } + + @Override + public Integer hello(Integer a, Integer b) { + context = RpcContext.getServerAttachment().getObjectAttachments(); + return a + b; + } + + @Override + public String error() { + throw new RuntimeException(); + } + + public static Map getAttachments() { + return context; + } + + @Override + public String getRemoteApplicationName() { + return RpcContext.getServiceContext().getRemoteApplicationName(); + } +} diff --git a/dubbo-test/dubbo-test-spring/pom.xml b/dubbo-test/dubbo-test-spring/pom.xml new file mode 100644 index 0000000000..3e417d36e6 --- /dev/null +++ b/dubbo-test/dubbo-test-spring/pom.xml @@ -0,0 +1,170 @@ + + + + dubbo-test + org.apache.dubbo + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-test-spring + + + true + 1.7.25 + 3.2.18.RELEASE + + + + + + + + + org.springframework + spring-framework-bom + ${spring_version} + pom + import + + + + + + + + org.apache.dubbo + dubbo-test-common + ${project.parent.version} + + + + + org.apache.dubbo + dubbo-registry-multicast + + + org.apache.dubbo + dubbo-registry-zookeeper + + + org.apache.dubbo + dubbo-registry-nacos + + + com.alibaba.nacos + nacos-client + + + org.apache.dubbo + dubbo-configcenter-zookeeper + + + org.apache.dubbo + dubbo-configcenter-nacos + + + org.apache.dubbo + dubbo-metadata-report-zookeeper + + + org.apache.dubbo + dubbo-metadata-report-nacos + + + org.apache.dubbo + dubbo-rpc-dubbo + + + org.apache.dubbo + dubbo-rpc-rest + + + org.apache.dubbo + dubbo-config-spring + + + org.apache.dubbo + dubbo-remoting-netty4 + + + org.apache.dubbo + dubbo-serialization-hessian2 + + + org.apache.dubbo + dubbo-serialization-jdk + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-log4j12 + ${slf4j-log4j12.version} + + + log4j + log4j + + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit_jupiter_version} + + + + org.junit.jupiter + junit-jupiter-params + ${junit_jupiter_version} + + + + org.hamcrest + hamcrest + ${hamcrest_version} + + + + org.mockito + mockito-core + ${mockito_version} + + + + org.mockito + mockito-inline + ${mockito_version} + + + + cglib + cglib-nodep + ${cglib_version} + + + + + diff --git a/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringAnnotationBeanTest.java b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringAnnotationBeanTest.java new file mode 100644 index 0000000000..d0cc44c500 --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringAnnotationBeanTest.java @@ -0,0 +1,67 @@ +/* + * 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.apache.dubbo.test.spring; + +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.apache.dubbo.test.common.ZooKeeperServer; +import org.apache.dubbo.test.common.api.DemoService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +public class SpringAnnotationBeanTest { + @BeforeAll + public static void beforeAll() { + ZooKeeperServer.start(); + DubboBootstrap.reset(); + } + + @Test + public void test() { + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestConfiguration.class); + TestService testService = applicationContext.getBean(TestService.class); + testService.test(); + } + + @EnableDubbo(scanBasePackages = "org.apache.dubbo.test.common.impl") + @Configuration + @PropertySource("/demo-app.properties") + static class TestConfiguration { + + @Bean + public TestService testService() { + return new TestService(); + } + } + + static class TestService { + + @DubboReference + private DemoService demoService; + + public void test() { + String result = demoService.sayHello("dubbo"); + Assertions.assertEquals("Hello dubbo", result); + } + } +} diff --git a/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringJavaConfigBeanTest.java b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringJavaConfigBeanTest.java new file mode 100644 index 0000000000..bcd2e5dcac --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringJavaConfigBeanTest.java @@ -0,0 +1,186 @@ +/* + * 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.apache.dubbo.test.spring; + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ConsumerConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.dubbo.config.annotation.DubboService; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.config.context.ConfigManager; +import org.apache.dubbo.config.spring.ReferenceBean; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; +import org.apache.dubbo.rpc.Constants; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.test.common.SysProps; +import org.apache.dubbo.test.common.ZooKeeperServer; +import org.apache.dubbo.test.common.api.DemoService; +import org.apache.dubbo.test.common.impl.DemoServiceImpl; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Collection; +import java.util.Map; + +public class SpringJavaConfigBeanTest { + + private static final String MY_PROTOCOL_ID = "myProtocol"; + private static final String MY_REGISTRY_ID = "my-registry"; + + @BeforeAll + public static void beforeAll() { + ZooKeeperServer.start(); + DubboBootstrap.reset(); + } + + @BeforeEach + public void beforeEach() { + DubboBootstrap.reset(); + } + + @AfterEach + public void afterEach() { + SysProps.clear(); + } + + @Test + public void testBean() { + + SysProps.setProperty("dubbo.application.owner", "Tom"); + SysProps.setProperty("dubbo.application.qos-enable", "false"); + SysProps.setProperty("dubbo.protocol.name", "dubbo"); + SysProps.setProperty("dubbo.protocol.port", "2346"); + String registryAddress = "zookeeper://127.0.0.1:2181"; + SysProps.setProperty("dubbo.registry.address", registryAddress); + SysProps.setProperty("dubbo.provider.group", "test"); + + AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext( + TestConfiguration.class, ConsumerConfiguration.class, ProviderConfiguration.class); + try { + consumerContext.start(); + + ConfigManager configManager = ApplicationModel.getConfigManager(); + ApplicationConfig application = configManager.getApplication().get(); + Assertions.assertEquals(false, application.getQosEnable()); + Assertions.assertEquals("Tom", application.getOwner()); + + RegistryConfig registry = configManager.getRegistry(MY_REGISTRY_ID).get(); + Assertions.assertEquals(registryAddress, registry.getAddress()); + + Collection protocols = configManager.getProtocols(); + Assertions.assertEquals(1, protocols.size()); + ProtocolConfig protocolConfig = protocols.iterator().next(); + Assertions.assertEquals("dubbo", protocolConfig.getName()); + Assertions.assertEquals(2346, protocolConfig.getPort()); + Assertions.assertEquals(MY_PROTOCOL_ID, protocolConfig.getId()); + + ConsumerConfig consumerConfig = configManager.getDefaultConsumer().get(); + Assertions.assertEquals(1000, consumerConfig.getTimeout()); + Assertions.assertEquals("demo", consumerConfig.getGroup()); + Assertions.assertEquals(false, consumerConfig.isCheck()); + Assertions.assertEquals(2, consumerConfig.getRetries()); + + Map referenceBeanMap = consumerContext.getBeansOfType(ReferenceBean.class); + Assertions.assertEquals(1, referenceBeanMap.size()); + ReferenceBean referenceBean = referenceBeanMap.get("&demoService"); + Assertions.assertNotNull(referenceBean); + ReferenceConfig referenceConfig = referenceBean.getReferenceConfig(); + // use consumer's attributes as default value + Assertions.assertEquals(consumerConfig.getTimeout(), referenceConfig.getTimeout()); + Assertions.assertEquals(consumerConfig.getGroup(), referenceConfig.getGroup()); + // consumer cannot override reference's attribute + Assertions.assertEquals(5, referenceConfig.getRetries()); + + DemoService referProxy = (DemoService) referenceConfig.get(); + Assertions.assertTrue( referProxy instanceof DemoService); + String result = referProxy.sayHello("dubbo"); + Assertions.assertEquals("Hello dubbo", result); + + } finally { + consumerContext.close(); + } + + } + + + @EnableDubbo(scanBasePackages = "") + @Configuration + static class TestConfiguration { + + @Bean(name = "dubbo-demo-application") + public ApplicationConfig applicationConfig() { + ApplicationConfig applicationConfig = new ApplicationConfig(); + applicationConfig.setName("dubbo-demo-application"); + return applicationConfig; + } + + @Bean(name = MY_PROTOCOL_ID) + public ProtocolConfig protocolConfig() { + ProtocolConfig protocolConfig = new ProtocolConfig(); + protocolConfig.setName("rest"); + protocolConfig.setPort(1234); + return protocolConfig; + } + + @Bean(name = MY_REGISTRY_ID) + public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("N/A"); + return registryConfig; + } + + @Bean + public ConsumerConfig consumerConfig() { + ConsumerConfig consumer = new ConsumerConfig(); + consumer.setTimeout(1000); + consumer.setGroup("demo"); + consumer.setCheck(false); + consumer.setRetries(2); + return consumer; + } + } + + @Configuration + static class ConsumerConfiguration { + + @Bean + @DubboReference(scope = Constants.SCOPE_LOCAL, retries = 5) + public ReferenceBean demoService() { + return new ReferenceBean<>(); + } + + } + + @Configuration + static class ProviderConfiguration { + + @Bean + @DubboService(group = "demo") + public DemoService demoServiceImpl() { + return new DemoServiceImpl(); + } + } +} diff --git a/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringXmlConfigTest.java b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringXmlConfigTest.java new file mode 100644 index 0000000000..492ee1aee7 --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/java/org/apache/dubbo/test/spring/SpringXmlConfigTest.java @@ -0,0 +1,66 @@ +/* + * 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.apache.dubbo.test.spring; + +import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import org.apache.dubbo.test.common.SysProps; +import org.apache.dubbo.test.common.ZooKeeperServer; +import org.apache.dubbo.test.common.api.DemoService; +import org.apache.dubbo.test.common.api.GreetingService; +import org.apache.dubbo.test.common.api.RestDemoService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY; + +public class SpringXmlConfigTest { + + @BeforeAll + public static void beforeAll() { + ZooKeeperServer.start(); + DubboBootstrap.reset(); + } + + @Test + public void test() { + SysProps.setProperty(SHUTDOWN_WAIT_KEY, "2000"); + ClassPathXmlApplicationContext applicationContext = null; + try { + applicationContext = new ClassPathXmlApplicationContext("/spring/dubbo-demo.xml"); + + GreetingService greetingService = applicationContext.getBean("greetingService", GreetingService.class); + String greeting = greetingService.hello(); + Assertions.assertEquals(greeting, "Greetings!"); + + DemoService demoService = applicationContext.getBean("demoService", DemoService.class); + String sayHelloResult = demoService.sayHello("dubbo"); + Assertions.assertTrue(sayHelloResult.startsWith("Hello dubbo"), sayHelloResult); + + RestDemoService restDemoService = applicationContext.getBean("restDemoService", RestDemoService.class); + String resetHelloResult = restDemoService.sayHello("dubbo"); + Assertions.assertEquals("Hello, dubbo", resetHelloResult); + } finally { + SysProps.clear(); + if (applicationContext != null) { + applicationContext.close(); + } + } + + } +} diff --git a/dubbo-test/dubbo-test-spring/src/main/resources/demo-app.properties b/dubbo-test/dubbo-test-spring/src/main/resources/demo-app.properties new file mode 100644 index 0000000000..f5bfdffb1e --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/resources/demo-app.properties @@ -0,0 +1,11 @@ + +dubbo.application.name=demo-app + +dubbo.registry.address=zookeeper://127.0.0.1:2181?registry-type=service + +dubbo.config-center.address=zookeeper://127.0.0.1:2181 + +dubbo.metadata-report.address=zookeeper://127.0.0.1:2181 + +dubbo.protocols.dubbo.port=-1 + diff --git a/dubbo-test/dubbo-test-spring/src/main/resources/log4j.properties b/dubbo-test/dubbo-test-spring/src/main/resources/log4j.properties new file mode 100644 index 0000000000..8de4c4fddb --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/resources/log4j.properties @@ -0,0 +1,7 @@ +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n diff --git a/dubbo-test/dubbo-test-spring/src/main/resources/spring/dubbo-demo.xml b/dubbo-test/dubbo-test-spring/src/main/resources/spring/dubbo-demo.xml new file mode 100644 index 0000000000..05392dabb5 --- /dev/null +++ b/dubbo-test/dubbo-test-spring/src/main/resources/spring/dubbo-demo.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dubbo-test/dubbo-test-spring3.2/pom.xml b/dubbo-test/dubbo-test-spring3.2/pom.xml new file mode 100644 index 0000000000..c349bdd833 --- /dev/null +++ b/dubbo-test/dubbo-test-spring3.2/pom.xml @@ -0,0 +1,70 @@ + + + + dubbo-test + org.apache.dubbo + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-test-spring3.2 + + + true + 3.2.18.RELEASE + + + + + + org.springframework + spring-framework-bom + ${spring_version} + pom + import + + + + + + + + org.apache.dubbo + dubbo-test-spring + ${project.parent.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.dubbo:dubbo-test-spring + + + + + + diff --git a/dubbo-test/dubbo-test-spring4.1/pom.xml b/dubbo-test/dubbo-test-spring4.1/pom.xml new file mode 100644 index 0000000000..942e0551a0 --- /dev/null +++ b/dubbo-test/dubbo-test-spring4.1/pom.xml @@ -0,0 +1,70 @@ + + + + dubbo-test + org.apache.dubbo + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-test-spring4.1 + + + true + 4.1.9.RELEASE + + + + + + org.springframework + spring-framework-bom + ${spring_version} + pom + import + + + + + + + + org.apache.dubbo + dubbo-test-spring + ${project.parent.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.dubbo:dubbo-test-spring + + + + + + diff --git a/dubbo-test/dubbo-test-spring4.2/pom.xml b/dubbo-test/dubbo-test-spring4.2/pom.xml new file mode 100644 index 0000000000..e53c596996 --- /dev/null +++ b/dubbo-test/dubbo-test-spring4.2/pom.xml @@ -0,0 +1,70 @@ + + + + dubbo-test + org.apache.dubbo + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-test-spring4.2 + + + true + 4.2.4.RELEASE + + + + + + org.springframework + spring-framework-bom + ${spring_version} + pom + import + + + + + + + + org.apache.dubbo + dubbo-test-spring + ${project.parent.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.dubbo:dubbo-test-spring + + + + + + diff --git a/dubbo-test/pom.xml b/dubbo-test/pom.xml new file mode 100644 index 0000000000..bc6fee2b6c --- /dev/null +++ b/dubbo-test/pom.xml @@ -0,0 +1,56 @@ + + + + org.apache.dubbo + dubbo-parent + ${revision} + ../pom.xml + + 4.0.0 + dubbo-test + pom + + + dubbo-test-common + dubbo-test-spring + dubbo-test-spring3.2 + dubbo-test-spring4.1 + dubbo-test-spring4.2 + + + + 8 + 8 + true + + + + + + org.apache.dubbo + dubbo-bom + ${project.parent.version} + pom + import + + + + + diff --git a/pom.xml b/pom.xml index a0ed38e61a..034699f378 100644 --- a/pom.xml +++ b/pom.xml @@ -153,6 +153,7 @@ dubbo-build-tools dubbo-spring-boot dubbo-native + dubbo-test @@ -691,6 +692,7 @@ + org.apache.maven.plugins maven-surefire-plugin ${maven_surefire_version}