[3.0] compatible with spring 3.2.x and add tests (#8430)

* compatible with spring 3.2.x and add tests

* add licence

* polish spring tests, fix compatible issue of spring 4.1

* polish code

* add skip_maven_deploy

* adjust spring test module

* polish log

* remove unused imports

* Fix NPE
This commit is contained in:
Gong Dewei 2021-08-10 11:25:11 +08:00 committed by GitHub
parent 0a07eaee65
commit 649dc5b396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1756 additions and 63 deletions

View File

@ -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;
}

View File

@ -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<BeanPostProcessor> 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<DemoService>
// 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

View File

@ -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<String> packagesToScan;
private Set<String> 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<String> 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<String, Object> 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<String> 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<String, Object> 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<String, Object> 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<? extends Annotation> annotationType : serviceAnnotationTypes) {
@ -542,7 +560,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos
Map<String, Object> 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);

View File

@ -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() {

View File

@ -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

View File

@ -79,21 +79,43 @@ public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistra
}
private Set<String> 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<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value));
packagesToScan.addAll(Arrays.asList(basePackages));
for (Class<?> basePackageClass : basePackageClasses) {
packagesToScan.add(ClassUtils.getPackageName(basePackageClass));
// get from @DubboComponentScan
Set<String> 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<String> getPackagesToScan0(AnnotationMetadata metadata, Class annotationClass, String basePackagesName, String basePackageClassesName) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(annotationClass.getName()));
if (attributes == null) {
return Collections.emptySet();
}
Set<String> 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;
}
}

View File

@ -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();

View File

@ -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<String, Map<String, Class>> 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;
}
}

View File

@ -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)) {

View File

@ -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> 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.
*
* <pre>
* Source method:
* ReferenceBean&lt;DemoService> demoService()
*
* Result: DemoService.class
* </pre>
*
* @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;
}
}

View File

@ -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)) {

View File

@ -0,0 +1,61 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-test</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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
* <p>
* Helper class to start an embedded instance of standalone (non clustered) ZooKeeper.
* <p>
* 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.
* <p>
* 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);
}
}
}
}
}

View File

@ -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);
}

View File

@ -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<String, String> map = new LinkedHashMap<String, String>();
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();
}
}

View File

@ -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();
}
}
}

View File

@ -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<String> sayHelloAsync(String name);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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<String> sayHelloAsync(String name) {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return "async result:" + name;
});
return cf;
}
}

View File

@ -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!";
}
}

View File

@ -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<String, Object> 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<String, Object> getAttachments() {
return context;
}
@Override
public String getRemoteApplicationName() {
return RpcContext.getServiceContext().getRemoteApplicationName();
}
}

View File

@ -0,0 +1,170 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-test</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test-spring</artifactId>
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<slf4j-log4j12.version>1.7.25</slf4j-log4j12.version>
<spring_version>3.2.18.RELEASE</spring_version>
<!--<spring_version>4.0.9.RELEASE</spring_version>-->
<!--<spring_version>4.1.9.RELEASE</spring_version>-->
<!--<spring_version>4.2.4.RELEASE</spring_version>-->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- test common -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-multicast</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-zookeeper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-zookeeper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-jdk</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<!--JUnit Jupiter Engine to depend on the JUnit5 engine and JUnit 5 API -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit_jupiter_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit_jupiter_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib_version}</version>
<!--<scope>test</scope>-->
</dependency>
</dependencies>
</project>

View File

@ -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);
}
}
}

View File

@ -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<ProtocolConfig> 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<String, ReferenceBean> 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> demoService() {
return new ReferenceBean<>();
}
}
@Configuration
static class ProviderConfiguration {
@Bean
@DubboService(group = "demo")
public DemoService demoServiceImpl() {
return new DemoServiceImpl();
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="demo-app" />
<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
<dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181?registry-type=service"/>
<dubbo:protocol name="dubbo" port="-1"/>
<dubbo:protocol name="rest" port="-1"/>
<bean id="demoServiceImpl" class="org.apache.dubbo.test.common.impl.DemoServiceImpl"/>
<bean id="greetingServiceImpl" class="org.apache.dubbo.test.common.impl.GreetingServiceImpl"/>
<bean id="restDemoServiceImpl" class="org.apache.dubbo.test.common.impl.RestDemoServiceImpl"/>
<dubbo:service interface="org.apache.dubbo.test.common.api.DemoService" timeout="3000" ref="demoServiceImpl" protocol="dubbo"/>
<dubbo:service version="1.0.0" group="greeting" timeout="5000" interface="org.apache.dubbo.test.common.api.GreetingService"
ref="greetingServiceImpl" protocol="dubbo"/>
<dubbo:service version="1.0.0" timeout="5000" interface="org.apache.dubbo.test.common.api.RestDemoService"
ref="restDemoServiceImpl" protocol="rest"/>
<!-- references -->
<dubbo:consumer check="false" scope="remote" />
<dubbo:reference id="demoService" scope="local"
interface="org.apache.dubbo.test.common.api.DemoService"/>
<dubbo:reference id="greetingService" version="1.0.0" group="greeting"
interface="org.apache.dubbo.test.common.api.GreetingService"/>
<dubbo:reference id="restDemoService" version="1.0.0" protocol="rest"
interface="org.apache.dubbo.test.common.api.RestDemoService"/>
</beans>

View File

@ -0,0 +1,70 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-test</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test-spring3.2</artifactId>
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring_version>3.2.18.RELEASE</spring_version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring test -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-spring</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<dependenciesToScan>
<dependency>org.apache.dubbo:dubbo-test-spring</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,70 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-test</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test-spring4.1</artifactId>
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring_version>4.1.9.RELEASE</spring_version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring test -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-spring</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<dependenciesToScan>
<dependency>org.apache.dubbo:dubbo-test-spring</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,70 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-test</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test-spring4.2</artifactId>
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
<spring_version>4.2.4.RELEASE</spring_version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- spring test -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-spring</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<dependenciesToScan>
<dependency>org.apache.dubbo:dubbo-test-spring</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
</project>

56
dubbo-test/pom.xml Normal file
View File

@ -0,0 +1,56 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-test</artifactId>
<packaging>pom</packaging>
<modules>
<module>dubbo-test-common</module>
<module>dubbo-test-spring</module>
<module>dubbo-test-spring3.2</module>
<module>dubbo-test-spring4.1</module>
<module>dubbo-test-spring4.2</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${project.parent.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -153,6 +153,7 @@
<module>dubbo-build-tools</module>
<module>dubbo-spring-boot</module>
<module>dubbo-native</module>
<module>dubbo-test</module>
</modules>
<dependencyManagement>
@ -691,6 +692,7 @@
<plugins>
<!-- keep surefire and failsafe in sync -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven_surefire_version}</version>
</plugin>