Polish /apache/dubbo#5721 : [Enhancement] Setting the default IDs for Dubbo's Config Beans (#5725)

This commit is contained in:
Mercy Ma 2020-02-10 20:13:03 +08:00 committed by GitHub
parent cd509a3b0c
commit 60e72bf5c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 206 additions and 121 deletions

View File

@ -0,0 +1,105 @@
/*
* 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.config;
import org.apache.dubbo.config.AbstractConfig;
import com.alibaba.spring.beans.factory.config.GenericBeanPostProcessorAdapter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.core.Ordered;
import javax.annotation.PostConstruct;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import static com.alibaba.spring.util.ObjectUtils.of;
import static org.springframework.aop.support.AopUtils.getTargetClass;
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
import static org.springframework.util.ReflectionUtils.invokeMethod;
/**
* The {@link BeanPostProcessor} class for the default property value of {@link AbstractConfig Dubbo's Config Beans}
*
* @since 2.7.6
*/
public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBeanPostProcessorAdapter<AbstractConfig>
implements MergedBeanDefinitionPostProcessor, Ordered {
/**
* The bean name of {@link DubboConfigDefaultPropertyValueBeanPostProcessor}
*/
public static final String BEAN_NAME = "dubboConfigDefaultPropertyValueBeanPostProcessor";
protected void processBeforeInitialization(AbstractConfig dubboConfigBean, String beanName) throws BeansException {
// [Feature] https://github.com/apache/dubbo/issues/5721
setBeanNameAsDefaultValue(dubboConfigBean, "id", beanName);
setBeanNameAsDefaultValue(dubboConfigBean, "name", beanName);
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// DO NOTHING
}
protected void setBeanNameAsDefaultValue(Object bean, String propertyName, String beanName) {
Class<?> beanClass = getTargetClass(bean);
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(beanClass, propertyName);
if (propertyDescriptor != null) { // the property is present
Method getNameMethod = propertyDescriptor.getReadMethod();
if (getNameMethod == null) { // if The getter method is absent
return;
}
Object propertyValue = invokeMethod(getNameMethod, bean);
if (propertyValue != null) { // If The return value of "getName" method is not null
return;
}
Method setNameMethod = propertyDescriptor.getWriteMethod();
if (setNameMethod != null) { // the getter and setter methods are present
if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
// set bean name to the value of the the property
invokeMethod(setNameMethod, bean, beanName);
}
}
}
}
/**
* @return Higher than {@link InitDestroyAnnotationBeanPostProcessor#getOrder()}
* @see InitDestroyAnnotationBeanPostProcessor
* @see CommonAnnotationBeanPostProcessor
* @see PostConstruct
*/
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE + 1;
}
}

View File

@ -33,6 +33,13 @@ import org.springframework.core.Ordered;
public class DubboBootstrapApplicationListener extends OneTimeExecutionApplicationContextEventListener
implements Ordered {
/**
* The bean name of {@link DubboBootstrapApplicationListener}
*
* @since 2.7.6
*/
public static final String BEAN_NAME = "dubboBootstrapApplicationListener";
private final DubboBootstrap dubboBootstrap;
public DubboBootstrapApplicationListener() {

View File

@ -41,6 +41,13 @@ import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncl
*/
public class DubboLifecycleComponentApplicationListener extends OneTimeExecutionApplicationContextEventListener {
/**
* The bean name of {@link DubboLifecycleComponentApplicationListener}
*
* @since 2.7.6
*/
public static final String BEAN_NAME = "dubboLifecycleComponentApplicationListener";
private List<Lifecycle> lifecycleComponents = emptyList();
@Override

View File

@ -20,7 +20,6 @@ import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@ -36,7 +35,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.config.spring.util.DubboBeanUtils.registerCommonBeans;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
/**
@ -58,8 +57,8 @@ public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistra
registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
registerReferenceAnnotationBeanPostProcessor(registry);
// @since 2.7.6 Register the common beans
registerCommonBeans(registry);
}
/**
@ -79,19 +78,6 @@ public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistra
}
/**
* Registers {@link ReferenceAnnotationBeanPostProcessor} into {@link BeanFactory}
*
* @param registry {@link BeanDefinitionRegistry}
*/
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// Register @Reference Annotation Bean Processor
registerInfrastructureBean(registry,
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(DubboComponentScan.class.getName()));

View File

@ -17,8 +17,6 @@
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigAliasPostProcessor;
import org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
@ -27,8 +25,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer.BEAN_NAME;
import static org.apache.dubbo.config.spring.util.DubboBeanUtils.registerCommonBeans;
/**
* Dubbo {@link AbstractConfig Config} {@link ImportBeanDefinitionRegistrar register}, which order can be configured
@ -55,26 +52,7 @@ public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRe
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
}
// Register DubboConfigAliasPostProcessor
registerDubboConfigAliasPostProcessor(registry);
// Register NamePropertyDefaultValueDubboConfigBeanCustomizer
registerDubboConfigBeanCustomizers(registry);
// Since 2.7.6
registerCommonBeans(registry);
}
private void registerDubboConfigBeanCustomizers(BeanDefinitionRegistry registry) {
registerInfrastructureBean(registry, BEAN_NAME, NamePropertyDefaultValueDubboConfigBeanCustomizer.class);
}
/**
* Register {@link DubboConfigAliasPostProcessor}
*
* @param registry {@link BeanDefinitionRegistry}
* @since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093
*/
private void registerDubboConfigAliasPostProcessor(BeanDefinitionRegistry registry) {
registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME, DubboConfigAliasPostProcessor.class);
}
}

View File

@ -30,7 +30,10 @@ import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.regis
* A {@link ImportBeanDefinitionRegistrar register} for the {@link Lifecycle Dubbo Lifecycle} components
*
* @since 2.7.5
* @deprecated as 2.7.6, Dubbo {@link Lifecycle} components will be registered automatically. Current class may be
* removed in the future
*/
@Deprecated
public class DubboLifecycleComponentRegistrar implements ImportBeanDefinitionRegistrar {
@Override

View File

@ -43,7 +43,6 @@ import java.lang.annotation.Target;
@Documented
@EnableDubboConfig
@DubboComponentScan
@EnableDubboLifecycle
public @interface EnableDubbo {
/**

View File

@ -18,8 +18,6 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.common.context.Lifecycle;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@ -31,11 +29,14 @@ import java.lang.annotation.Target;
* Enables Dubbo {@link Lifecycle} components
*
* @since 2.7.5
* @deprecated as 2.7.6, Dubbo {@link Lifecycle} components will be registered automatically. Current annotation may be
* removed in the future
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboLifecycleComponentRegistrar.class)
//@Import(DubboLifecycleComponentRegistrar.class) // Disabled since 2.7.6
@Deprecated
public @interface EnableDubboLifecycle {
}

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.config;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigDefaultPropertyValueBeanPostProcessor;
import org.springframework.util.ReflectionUtils;
@ -32,7 +33,9 @@ import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
* if absent.
*
* @since 2.6.6
* @deprecated As 2.7.6, use {@link DubboConfigDefaultPropertyValueBeanPostProcessor}
*/
@Deprecated
public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboConfigBeanCustomizer {
/**

View File

@ -19,15 +19,13 @@ package org.apache.dubbo.config.spring.schema;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.config.spring.util.DubboBeanUtils.registerCommonBeans;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
import static org.springframework.util.StringUtils.trimArrayElements;
@ -60,9 +58,8 @@ public class AnnotationBeanDefinitionParser extends AbstractSingleBeanDefinition
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// Registers ReferenceAnnotationBeanPostProcessor
registerReferenceAnnotationBeanPostProcessor(parserContext.getRegistry());
// @since 2.7.6 Register the common beans
registerCommonBeans(parserContext.getRegistry());
}
@Override
@ -70,19 +67,6 @@ public class AnnotationBeanDefinitionParser extends AbstractSingleBeanDefinition
return true;
}
/**
* Registers {@link ReferenceAnnotationBeanPostProcessor} into {@link BeanFactory}
*
* @param registry {@link BeanDefinitionRegistry}
*/
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// Register @Reference Annotation Bean Processor
registerInfrastructureBean(registry,
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
@Override
protected Class<?> getBeanClass(Element element) {
return ServiceAnnotationBeanPostProcessor.class;

View File

@ -0,0 +1,68 @@
/*
* 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.dubbo.config.spring.beans.factory.annotation.DubboConfigAliasPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigDefaultPropertyValueBeanPostProcessor;
import org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener;
import org.apache.dubbo.config.spring.context.DubboLifecycleComponentApplicationListener;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
/**
* Dubbo Bean utilities class
*
* @since 2.7.6
*/
public interface DubboBeanUtils {
/**
* Register the common beans
*
* @param registry {@link BeanDefinitionRegistry}
* @see ReferenceAnnotationBeanPostProcessor
* @see DubboConfigDefaultPropertyValueBeanPostProcessor
* @see DubboConfigAliasPostProcessor
* @see DubboLifecycleComponentApplicationListener
* @see DubboBootstrapApplicationListener
*/
static void registerCommonBeans(BeanDefinitionRegistry registry) {
// Since 2.5.7 Register @Reference Annotation Bean Processor as an infrastructure Bean
registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
ReferenceAnnotationBeanPostProcessor.class);
// Since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093
registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
DubboConfigAliasPostProcessor.class);
// Since 2.7.5 Register DubboLifecycleComponentApplicationListener as an infrastructure Bean
registerInfrastructureBean(registry, DubboLifecycleComponentApplicationListener.BEAN_NAME,
DubboLifecycleComponentApplicationListener.class);
// Since 2.7.4 Register DubboBootstrapApplicationListener as an infrastructure Bean
registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME,
DubboBootstrapApplicationListener.class);
// ince 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean
registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
DubboConfigDefaultPropertyValueBeanPostProcessor.class);
}
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* {@link EnableDubboLifecycle} Test
*
* @since 2.7.5
*/
@EnableDubboLifecycle
public class EnableDubboLifecycleTest {
private AnnotationConfigApplicationContext context;
@BeforeEach
public void init() {
ApplicationModel.getConfigManager().setApplication(new ApplicationConfig("EnableDubboLifecycleTest"));
context = new AnnotationConfigApplicationContext(EnableDubboLifecycleTest.class);
}
@AfterEach
public void destroy() {
context.close();
}
@Test
public void test() {
assertTrue(DubboBootstrap.getInstance().isInitialized());
assertTrue(DubboBootstrap.getInstance().isStarted());
}
}