This is an automated email from the ASF dual-hosted git repository. mercyblitz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/master by this push: new 7e43315 [Refactor] Rename the class name of ServiceAnnotationBeanPostProcessor (#6070) 7e43315 is described below commit 7e43315cd62a47803d786a1a04002203a4512d4e Author: Mercy Ma <mercybl...@gmail.com> AuthorDate: Mon Apr 27 16:10:05 2020 +0800 [Refactor] Rename the class name of ServiceAnnotationBeanPostProcessor (#6070) * Polish apache/dubbo#4830 : [Refactor] Rename the class name of ServiceAnnotationBeanPostProcessor * Polish apache/dubbo#4830 : Remove unused import --- .../ServiceAnnotationBeanPostProcessor.java | 491 +-------------------- ...ocessor.java => ServiceClassPostProcessor.java} | 32 +- .../ServiceAnnotationTestConfiguration2.java | 115 +++++ .../annotation/ServiceClassPostProcessorTest.java | 95 ++++ 4 files changed, 231 insertions(+), 502 deletions(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java index 08a0965..3c9457c 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java @@ -16,83 +16,23 @@ */ package org.apache.dubbo.config.spring.beans.factory.annotation; -import org.apache.dubbo.common.logger.Logger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.config.MethodConfig; -import org.apache.dubbo.config.annotation.Method; import org.apache.dubbo.config.annotation.Service; -import org.apache.dubbo.config.spring.ServiceBean; -import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener; -import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner; -import org.springframework.beans.BeansException; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.config.SingletonBeanRegistry; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.context.annotation.AnnotationBeanNameGenerator; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; -import org.springframework.context.annotation.ConfigurationClassPostProcessor; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.env.Environment; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; -import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; import java.util.Set; -import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans; -import static com.alibaba.spring.util.ObjectUtils.of; -import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create; -import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveServiceInterfaceClass; -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.core.annotation.AnnotationUtils.getAnnotationAttributes; -import static org.springframework.util.ClassUtils.resolveClassName; - /** - * {@link Service} Annotation - * {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor} + * {@link Service} Annotation {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor} * * @since 2.5.8 + * @deprecated Recommend {@link ServiceClassPostProcessor} as the substitute */ -public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, - ResourceLoaderAware, BeanClassLoaderAware { - - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final Set<String> packagesToScan; - - private Environment environment; - - private ResourceLoader resourceLoader; - - private ClassLoader classLoader; +@Deprecated +public class ServiceAnnotationBeanPostProcessor extends ServiceClassPostProcessor { public ServiceAnnotationBeanPostProcessor(String... packagesToScan) { this(Arrays.asList(packagesToScan)); @@ -103,429 +43,8 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr } public ServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) { - this.packagesToScan = packagesToScan; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - - // @since 2.7.5 - registerBeans(registry, DubboBootstrapApplicationListener.class); - - Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); - - if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) { - registerServiceBeans(resolvedPackagesToScan, registry); - } else { - if (logger.isWarnEnabled()) { - logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!"); - } - } - - } - - - /** - * Registers Beans whose classes was annotated {@link Service} - * - * @param packagesToScan The base packages to scan - * @param registry {@link BeanDefinitionRegistry} - */ - private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) { - - DubboClassPathBeanDefinitionScanner scanner = - new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader); - - BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry); - - scanner.setBeanNameGenerator(beanNameGenerator); - - scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class)); - - /** - * Add the compatibility for legacy Dubbo's @Service - * - * The issue : https://github.com/apache/dubbo/issues/4330 - * @since 2.7.3 - */ - scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class)); - - for (String packageToScan : packagesToScan) { - - // Registers @Service Bean first - scanner.scan(packageToScan); - - // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not. - Set<BeanDefinitionHolder> beanDefinitionHolders = - findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator); - - if (!CollectionUtils.isEmpty(beanDefinitionHolders)) { - - for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) { - registerServiceBean(beanDefinitionHolder, registry, scanner); - } - - if (logger.isInfoEnabled()) { - logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " + - beanDefinitionHolders + - " } were scanned under package[" + packageToScan + "]"); - } - - } else { - - if (logger.isWarnEnabled()) { - logger.warn("No Spring Bean annotating Dubbo's @Service was found under package[" - + packageToScan + "]"); - } - - } - - } - - } - - /** - * It'd better to use BeanNameGenerator instance that should reference - * {@link ConfigurationClassPostProcessor#componentScanBeanNameGenerator}, - * thus it maybe a potential problem on bean name generation. - * - * @param registry {@link BeanDefinitionRegistry} - * @return {@link BeanNameGenerator} instance - * @see SingletonBeanRegistry - * @see AnnotationConfigUtils#CONFIGURATION_BEAN_NAME_GENERATOR - * @see ConfigurationClassPostProcessor#processConfigBeanDefinitions - * @since 2.5.8 - */ - private BeanNameGenerator resolveBeanNameGenerator(BeanDefinitionRegistry registry) { - - BeanNameGenerator beanNameGenerator = null; - - if (registry instanceof SingletonBeanRegistry) { - SingletonBeanRegistry singletonBeanRegistry = SingletonBeanRegistry.class.cast(registry); - beanNameGenerator = (BeanNameGenerator) singletonBeanRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); - } - - if (beanNameGenerator == null) { - - if (logger.isInfoEnabled()) { - - logger.info("BeanNameGenerator bean can't be found in BeanFactory with name [" - + CONFIGURATION_BEAN_NAME_GENERATOR + "]"); - logger.info("BeanNameGenerator will be a instance of " + - AnnotationBeanNameGenerator.class.getName() + - " , it maybe a potential problem on bean name generation."); - } - - beanNameGenerator = new AnnotationBeanNameGenerator(); - - } - - return beanNameGenerator; - - } - - /** - * Finds a {@link Set} of {@link BeanDefinitionHolder BeanDefinitionHolders} whose bean type annotated - * {@link Service} Annotation. - * - * @param scanner {@link ClassPathBeanDefinitionScanner} - * @param packageToScan pachage to scan - * @param registry {@link BeanDefinitionRegistry} - * @return non-null - * @since 2.5.8 - */ - private Set<BeanDefinitionHolder> findServiceBeanDefinitionHolders( - ClassPathBeanDefinitionScanner scanner, String packageToScan, BeanDefinitionRegistry registry, - BeanNameGenerator beanNameGenerator) { - - Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(packageToScan); - - Set<BeanDefinitionHolder> beanDefinitionHolders = new LinkedHashSet<>(beanDefinitions.size()); - - for (BeanDefinition beanDefinition : beanDefinitions) { - - String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry); - BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, beanName); - beanDefinitionHolders.add(beanDefinitionHolder); - - } - - return beanDefinitionHolders; - - } - - /** - * Registers {@link ServiceBean} from new annotated {@link Service} {@link BeanDefinition} - * - * @param beanDefinitionHolder - * @param registry - * @param scanner - * @see ServiceBean - * @see BeanDefinition - */ - private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry, - DubboClassPathBeanDefinitionScanner scanner) { - - Class<?> beanClass = resolveClass(beanDefinitionHolder); - - Annotation service = findServiceAnnotation(beanClass); - - /** - * The {@link AnnotationAttributes} of @Service annotation - */ - AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false); - - Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass); - - String annotatedServiceBeanName = beanDefinitionHolder.getBeanName(); - - AbstractBeanDefinition serviceBeanDefinition = - buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName); - - // ServiceBean Bean name - String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass); - - if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean - registry.registerBeanDefinition(beanName, serviceBeanDefinition); - - if (logger.isInfoEnabled()) { - logger.info("The BeanDefinition[" + serviceBeanDefinition + - "] of ServiceBean has been registered with name : " + beanName); - } - - } else { - - if (logger.isWarnEnabled()) { - logger.warn("The Duplicated BeanDefinition[" + serviceBeanDefinition + - "] of ServiceBean[ bean name : " + beanName + - "] was be found , Did @DubboComponentScan scan to same package in many times?"); - } - - } - - } - - - /** - * Find the {@link Annotation annotation} of @Service - * - * @param beanClass the {@link Class class} of Bean - * @return <code>null</code> if not found - * @since 2.7.3 - */ - private Annotation findServiceAnnotation(Class<?> beanClass) { - Annotation service = findMergedAnnotation(beanClass, Service.class); - if (service == null) { - service = findMergedAnnotation(beanClass, com.alibaba.dubbo.config.annotation.Service.class); - } - return service; - } - - /** - * Generates the bean name of {@link ServiceBean} - * - * @param serviceAnnotationAttributes - * @param interfaceClass the class of interface annotated {@link Service} - * @return ServiceBean@interfaceClassName#annotatedServiceBeanName - * @since 2.7.3 - */ - private String generateServiceBeanName(AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass) { - ServiceBeanNameBuilder builder = create(interfaceClass, environment) - .group(serviceAnnotationAttributes.getString("group")) - .version(serviceAnnotationAttributes.getString("version")); - return builder.build(); - } - - private Class<?> resolveClass(BeanDefinitionHolder beanDefinitionHolder) { - - BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition(); - - return resolveClass(beanDefinition); - - } - - private Class<?> resolveClass(BeanDefinition beanDefinition) { - - String beanClassName = beanDefinition.getBeanClassName(); - - return resolveClassName(beanClassName, classLoader); - - } - - private Set<String> resolvePackagesToScan(Set<String> packagesToScan) { - Set<String> resolvedPackagesToScan = new LinkedHashSet<String>(packagesToScan.size()); - for (String packageToScan : packagesToScan) { - if (StringUtils.hasText(packageToScan)) { - String resolvedPackageToScan = environment.resolvePlaceholders(packageToScan.trim()); - resolvedPackagesToScan.add(resolvedPackageToScan); - } - } - return resolvedPackagesToScan; - } - - /** - * Build the {@link AbstractBeanDefinition Bean Definition} - * - * @param serviceAnnotation - * @param serviceAnnotationAttributes - * @param interfaceClass - * @param annotatedServiceBeanName - * @return - * @since 2.7.3 - */ - private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation, - AnnotationAttributes serviceAnnotationAttributes, - Class<?> interfaceClass, - String annotatedServiceBeanName) { - - BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class); - - AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); - - MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); - - String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", - "interface", "interfaceName", "parameters"); - - propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotation, environment, ignoreAttributeNames)); - - // References "ref" property to annotated-@Service Bean - addPropertyReference(builder, "ref", annotatedServiceBeanName); - // Set interface - builder.addPropertyValue("interface", interfaceClass.getName()); - // Convert parameters into map - builder.addPropertyValue("parameters", convertParameters(serviceAnnotationAttributes.getStringArray("parameters"))); - // Add methods parameters - List<MethodConfig> methodConfigs = convertMethodConfigs(serviceAnnotationAttributes.get("methods")); - if (!methodConfigs.isEmpty()) { - builder.addPropertyValue("methods", methodConfigs); - } - - /** - * Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference - */ - String providerConfigBeanName = serviceAnnotationAttributes.getString("provider"); - if (StringUtils.hasText(providerConfigBeanName)) { - addPropertyReference(builder, "provider", providerConfigBeanName); - } - - /** - * Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference - */ - String monitorConfigBeanName = serviceAnnotationAttributes.getString("monitor"); - if (StringUtils.hasText(monitorConfigBeanName)) { - addPropertyReference(builder, "monitor", monitorConfigBeanName); - } - - /** - * Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference - */ - String applicationConfigBeanName = serviceAnnotationAttributes.getString("application"); - if (StringUtils.hasText(applicationConfigBeanName)) { - addPropertyReference(builder, "application", applicationConfigBeanName); - } - - /** - * Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference - */ - String moduleConfigBeanName = serviceAnnotationAttributes.getString("module"); - if (StringUtils.hasText(moduleConfigBeanName)) { - addPropertyReference(builder, "module", moduleConfigBeanName); - } - - - /** - * Add {@link org.apache.dubbo.config.RegistryConfig} Bean reference - */ - String[] registryConfigBeanNames = serviceAnnotationAttributes.getStringArray("registry"); - - List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames); - - if (!registryRuntimeBeanReferences.isEmpty()) { - builder.addPropertyValue("registries", registryRuntimeBeanReferences); - } - - /** - * Add {@link org.apache.dubbo.config.ProtocolConfig} Bean reference - */ - String[] protocolConfigBeanNames = serviceAnnotationAttributes.getStringArray("protocol"); - - List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames); - - if (!protocolRuntimeBeanReferences.isEmpty()) { - builder.addPropertyValue("protocols", protocolRuntimeBeanReferences); - } - - return builder.getBeanDefinition(); - - } - - private List convertMethodConfigs(Object methodsAnnotation) { - if (methodsAnnotation == null) { - return Collections.EMPTY_LIST; - } - return MethodConfig.constructMethodConfig((Method[]) methodsAnnotation); + super(packagesToScan); } - private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) { - - ManagedList<RuntimeBeanReference> runtimeBeanReferences = new ManagedList<>(); - - if (!ObjectUtils.isEmpty(beanNames)) { - - for (String beanName : beanNames) { - - String resolvedBeanName = environment.resolvePlaceholders(beanName); - - runtimeBeanReferences.add(new RuntimeBeanReference(resolvedBeanName)); - } - - } - - return runtimeBeanReferences; - - } - - private void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, String beanName) { - String resolvedBeanName = environment.resolvePlaceholders(beanName); - builder.addPropertyReference(propertyName, resolvedBeanName); - } - - - private Map<String, String> convertParameters(String[] parameters) { - if (ArrayUtils.isEmpty(parameters)) { - return null; - } - - if (parameters.length % 2 != 0) { - throw new IllegalArgumentException("parameter attribute must be paired with key followed by value"); - } - - Map<String, String> map = new HashMap<>(); - for (int i = 0; i < parameters.length; i += 2) { - map.put(parameters[i], parameters[i + 1]); - } - return map; - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - - } - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } } \ No newline at end of file diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessor.java similarity index 95% copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java copy to dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessor.java index 08a0965..acda5f0 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessor.java @@ -25,12 +25,14 @@ import org.apache.dubbo.config.annotation.Service; import org.apache.dubbo.config.spring.ServiceBean; import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener; import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner; +import org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanClassLoaderAware; 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.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.config.SingletonBeanRegistry; @@ -40,6 +42,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.AnnotationBeanNameGenerator; @@ -55,7 +58,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import java.lang.annotation.Annotation; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -66,6 +68,7 @@ import java.util.Set; import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans; import static com.alibaba.spring.util.ObjectUtils.of; +import static java.util.Arrays.asList; import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create; import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveServiceInterfaceClass; import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition; @@ -75,18 +78,19 @@ import static org.springframework.core.annotation.AnnotationUtils.getAnnotationA import static org.springframework.util.ClassUtils.resolveClassName; /** - * {@link Service} Annotation - * {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor} + * {@link BeanFactoryPostProcessor} used for processing of {@link Service @Service} annotated classes. it's also the + * infrastructure class of XML {@link BeanDefinitionParser} on <dubbbo:annotation /> * - * @since 2.5.8 + * @see AnnotationBeanDefinitionParser + * @see BeanDefinitionRegistryPostProcessor + * @since 2.7.7 */ -public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, +public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ResourceLoaderAware, BeanClassLoaderAware { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final Set<String> packagesToScan; + protected final Set<String> packagesToScan; private Environment environment; @@ -94,15 +98,15 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr private ClassLoader classLoader; - public ServiceAnnotationBeanPostProcessor(String... packagesToScan) { - this(Arrays.asList(packagesToScan)); + public ServiceClassPostProcessor(String... packagesToScan) { + this(asList(packagesToScan)); } - public ServiceAnnotationBeanPostProcessor(Collection<String> packagesToScan) { + public ServiceClassPostProcessor(Collection<String> packagesToScan) { this(new LinkedHashSet<>(packagesToScan)); } - public ServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) { + public ServiceClassPostProcessor(Set<String> packagesToScan) { this.packagesToScan = packagesToScan; } @@ -124,7 +128,6 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr } - /** * Registers Beans whose classes was annotated {@link Service} * @@ -305,7 +308,6 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr } - /** * Find the {@link Annotation annotation} of @Service * @@ -491,7 +493,6 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr builder.addPropertyReference(propertyName, resolvedBeanName); } - private Map<String, String> convertParameters(String[] parameters) { if (ArrayUtils.isEmpty(parameters)) { return null; @@ -527,5 +528,4 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } - -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration2.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration2.java new file mode 100644 index 0000000..5927f43 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationTestConfiguration2.java @@ -0,0 +1,115 @@ +/* + * 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.beans.factory.annotation; + + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.annotation.Service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.PropertySource; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionStatus; + +/** + * {@link Service} Bean + * + * @since 2.7.7 + */ +@PropertySource("classpath:/META-INF/default.properties") +public class ServiceAnnotationTestConfiguration2 { + + /** + * Current application configuration, to replace XML config: + * <prev> + * <dubbo:application name="dubbo-demo-application"/> + * </prev> + * + * @return {@link ApplicationConfig} Bean + */ + @Bean("dubbo-demo-application") + public ApplicationConfig applicationConfig() { + ApplicationConfig applicationConfig = new ApplicationConfig(); + applicationConfig.setName("dubbo-demo-application"); + return applicationConfig; + } + + /** + * Current registry center configuration, to replace XML config: + * <prev> + * <dubbo:registry id="my-registry" address="N/A"/> + * </prev> + * + * @return {@link RegistryConfig} Bean + */ + @Bean("my-registry") + public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("N/A"); + return registryConfig; + } + + /** + * Current protocol configuration, to replace XML config: + * <prev> + * <dubbo:protocol name="dubbo" port="12345"/> + * </prev> + * + * @return {@link ProtocolConfig} Bean + */ + @Bean("dubbo") + public ProtocolConfig protocolConfig() { + ProtocolConfig protocolConfig = new ProtocolConfig(); + protocolConfig.setName("dubbo"); + protocolConfig.setPort(12345); + return protocolConfig; + } + + @Primary + @Bean + public PlatformTransactionManager platformTransactionManager() { + return new PlatformTransactionManager() { + + @Override + public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { + return null; + } + + @Override + public void commit(TransactionStatus status) throws TransactionException { + + } + + @Override + public void rollback(TransactionStatus status) throws TransactionException { + + } + }; + } + + @Bean + public ServiceClassPostProcessor serviceClassPostProcessor(@Value("${packagesToScan}") String... packagesToScan) { + return new ServiceClassPostProcessor(packagesToScan); + } + +} \ No newline at end of file diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java new file mode 100644 index 0000000..4422e75 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java @@ -0,0 +1,95 @@ +/* + * 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.beans.factory.annotation; + +import org.apache.dubbo.config.spring.ServiceBean; +import org.apache.dubbo.config.spring.api.HelloService; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Map; + +/** + * {@link ServiceClassPostProcessor} Test + * + * @since 2.7.7 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration( + classes = { + ServiceAnnotationTestConfiguration2.class, + ServiceClassPostProcessorTest.class + }) +@TestPropertySource(properties = { + "provider.package = org.apache.dubbo.config.spring.context.annotation.provider", + "packagesToScan = ${provider.package}", +}) +public class ServiceClassPostProcessorTest { + + @Autowired + private ConfigurableListableBeanFactory beanFactory; + + @Bean + public ServiceClassPostProcessor serviceClassPostProcessor2 + (@Value("${packagesToScan}") String... packagesToScan) { + return new ServiceClassPostProcessor(packagesToScan); + } + + @Test + public void test() { + + Map<String, HelloService> helloServicesMap = beanFactory.getBeansOfType(HelloService.class); + + Assert.assertEquals(2, helloServicesMap.size()); + + Map<String, ServiceBean> serviceBeansMap = beanFactory.getBeansOfType(ServiceBean.class); + + Assert.assertEquals(2, serviceBeansMap.size()); + + Map<String, ServiceClassPostProcessor> beanPostProcessorsMap = + beanFactory.getBeansOfType(ServiceClassPostProcessor.class); + + Assert.assertEquals(2, beanPostProcessorsMap.size()); + + Assert.assertTrue(beanPostProcessorsMap.containsKey("serviceClassPostProcessor")); + Assert.assertTrue(beanPostProcessorsMap.containsKey("serviceClassPostProcessor2")); + + } + + @Test + public void testMethodAnnotation() { + + Map<String, ServiceBean> serviceBeansMap = beanFactory.getBeansOfType(ServiceBean.class); + + Assert.assertEquals(2, serviceBeansMap.size()); + + ServiceBean demoServiceBean = serviceBeansMap.get("ServiceBean:org.apache.dubbo.config.spring.api.DemoService:2.5.7"); + + Assert.assertNotNull(demoServiceBean.getMethods()); + + } + +}