You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/11/25 06:20:09 UTC
[dubbo] 23/45: improve config bean initialization
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch release/3.0.14-rpccontext-bugfix
in repository https://gitbox.apache.org/repos/asf/dubbo.git
commit 278aaef1acad984bf33c1ab387772c4621d86088
Author: 赫炎 <de...@alibaba-inc.com>
AuthorDate: Tue Dec 1 22:43:20 2020 +0800
improve config bean initialization
---
.../org/apache/dubbo/config/AbstractConfig.java | 4 +-
.../apache/dubbo/config/spring/ReferenceBean.java | 59 ++------
.../annotation/DubboConfigAliasPostProcessor.java | 3 +
.../config/DubboConfigBeanPostProcessor.java | 149 +++++++++++++++++++++
...onfigDefaultPropertyValueBeanPostProcessor.java | 2 +
.../dubbo/config/spring/util/DubboBeanUtils.java | 13 +-
6 files changed, 172 insertions(+), 58 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 16e1180..ab8f5f4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@ -571,10 +571,12 @@ public abstract class AbstractConfig implements Serializable {
* <p>
* Current method will invoked by Spring or Java EE container automatically, or should be triggered manually.
*
+ * @deprecated this init method is replace with DubboConfigBeanPostProcessor
+ *
* @see ConfigManager#addConfig(AbstractConfig)
* @since 2.7.5
*/
- @PostConstruct
+ @Deprecated
public void addIntoConfigManager() {
ApplicationModel.getConfigManager().addConfig(this);
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
index be9cd71..4ca3a84 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
@@ -16,34 +16,22 @@
*/
package org.apache.dubbo.config.spring;
-import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ConsumerConfig;
-import org.apache.dubbo.config.MetadataReportConfig;
-import org.apache.dubbo.config.MetricsConfig;
-import org.apache.dubbo.config.ModuleConfig;
-import org.apache.dubbo.config.MonitorConfig;
-import org.apache.dubbo.config.ProtocolConfig;
-import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.ReferenceConfig;
-import org.apache.dubbo.config.RegistryConfig;
-import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigBeanPostProcessor;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.apache.dubbo.config.support.Parameter;
-
-import org.springframework.beans.factory.DisposableBean;
+import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
-import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
-
/**
* ReferenceFactoryBean
*/
-public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
- ApplicationContextAware, InitializingBean, DisposableBean {
+public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware,
+ InitializingBean {
private static final long serialVersionUID = 213195494150089726L;
@@ -79,43 +67,14 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
return true;
}
- /**
- * Initializes there Dubbo's Config Beans before @Reference bean autowiring
- */
- private void prepareDubboConfigBeans() {
- beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, ConfigCenterBean.class);
- beansOfTypeIncludingAncestors(applicationContext, MetadataReportConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, MetricsConfig.class);
- beansOfTypeIncludingAncestors(applicationContext, SslConfig.class);
- }
-
@Override
- @SuppressWarnings({"unchecked"})
public void afterPropertiesSet() throws Exception {
-
- // Initializes Dubbo's Config Beans before @Reference bean autowiring
- prepareDubboConfigBeans();
-
- // lazy init by default.
- if (init == null) {
- init = false;
+ // Abort initializing when config beans are not loaded
+ if (!DubboConfigBeanPostProcessor.isConfigBeansLoaded()) {
+ throw new IllegalStateException("dubbo config beans are not loaded");
}
- // eager init if necessary.
- if (shouldInit()) {
- getObject();
- }
- }
-
- @Override
- public void destroy() {
- // do nothing
+ // Abort initializing when property values are not autowired probably
+ ConfigValidationUtils.validateReferenceConfig(this);
}
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
index 28b6a6c..5f55343 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
@@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.dubbo.config.AbstractConfig;
+import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigBeanPostProcessor;
import org.apache.dubbo.config.spring.context.annotation.DubboConfigConfigurationRegistrar;
import org.springframework.beans.BeansException;
@@ -32,8 +33,10 @@ import static org.springframework.util.StringUtils.hasText;
/**
* A Post-Processor class to set the alias of Dubbo Config bean using its {@link AbstractConfig#getId()}
*
+ * @deprecated replace with {@link DubboConfigBeanPostProcessor}
* @since 2.7.5
*/
+@Deprecated
public class DubboConfigAliasPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanPostProcessor {
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigBeanPostProcessor.java
new file mode 100644
index 0000000..fb72ce8
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigBeanPostProcessor.java
@@ -0,0 +1,149 @@
+/*
+ * 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.common.utils.StringUtils;
+import org.apache.dubbo.config.AbstractConfig;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.SslConfig;
+import org.apache.dubbo.config.spring.ConfigCenterBean;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.alibaba.spring.util.BeanRegistrar.hasAlias;
+import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
+import static org.springframework.util.ObjectUtils.nullSafeEquals;
+import static org.springframework.util.StringUtils.hasText;
+
+/**
+ * A Post-Processor to config Dubbo Config bean
+ *
+ * @since 2.7.9
+ */
+public class DubboConfigBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanPostProcessor,
+ ApplicationContextAware {
+
+ /**
+ * The bean name of {@link DubboConfigBeanPostProcessor}
+ */
+ public final static String BEAN_NAME = "dubboConfigBeanPostProcessor";
+
+ private BeanDefinitionRegistry registry;
+ private ApplicationContext applicationContext;
+ private static AtomicBoolean configBeansLoading = new AtomicBoolean();
+ private static volatile boolean configBeansLoaded;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ this.registry = registry;
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // DO NOTHING
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (configBeansLoading.compareAndSet(false, true)) {
+ // Initializes Dubbo's Config Beans before @Reference bean autowiring
+ prepareDubboConfigBeans();
+ configBeansLoaded = true;
+ }
+
+ // DO NOTHING
+ return bean;
+ }
+
+ private void prepareDubboConfigBeans() {
+ // Refactor 2.7.9
+ final boolean includeNonSingletons = true;
+ final boolean allowEagerInit = false;
+ beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, ConfigCenterBean.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, MetadataReportConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, MetricsConfig.class, includeNonSingletons, allowEagerInit);
+ beansOfTypeIncludingAncestors(applicationContext, SslConfig.class, includeNonSingletons, allowEagerInit);
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof AbstractConfig) {
+ AbstractConfig configBean = (AbstractConfig) bean;
+ setDefaultConfigId(configBean, beanName);
+ setConfigBeanAlias(configBean, beanName);
+ addConfigBeanToManager(configBean);
+ }
+ return bean;
+ }
+
+ private void setDefaultConfigId(AbstractConfig configBean, String beanName) {
+ // if config bean's id is not set, use beanName as config id
+ // https://github.com/apache/dubbo/issues/5721
+ if (StringUtils.isEmpty(configBean.getId())) {
+ configBean.setId(beanName);
+ }
+ }
+
+ private void setConfigBeanAlias(AbstractConfig configBean, String beanName) {
+ // set dubbo config bean alias from id property
+ // https://github.com/apache/dubbo/issues/5093
+ String id = configBean.getId();
+ if (hasText(id) // id MUST be present in AbstractConfig
+ && !nullSafeEquals(id, beanName) // id MUST NOT be equal to bean name
+ && !hasAlias(registry, beanName, id)) { // id MUST NOT be present in AliasRegistry
+ registry.registerAlias(beanName, id);
+ }
+ }
+
+ private void addConfigBeanToManager(AbstractConfig configBean) {
+ // Add AbstractConfig instance into ConfigManager,
+ // no need to call org.apache.dubbo.config.AbstractConfig.addIntoConfigManager()
+ ApplicationModel.getConfigManager().addConfig(configBean);
+ }
+
+ public static boolean isConfigBeansLoaded() {
+ return configBeansLoaded;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java
index ec99c1c..52f52d6 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java
@@ -41,8 +41,10 @@ import static org.springframework.util.ReflectionUtils.invokeMethod;
/**
* The {@link BeanPostProcessor} class for the default property value of {@link AbstractConfig Dubbo's Config Beans}
*
+ * @deprecated replace with {@link DubboConfigBeanPostProcessor}
* @since 2.7.6
*/
+@Deprecated
public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBeanPostProcessorAdapter<AbstractConfig>
implements MergedBeanDefinitionPostProcessor, PriorityOrdered {
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java
index 3b2c31c..03dd533 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboBeanUtils.java
@@ -18,6 +18,7 @@ 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.DubboConfigBeanPostProcessor;
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;
@@ -49,10 +50,6 @@ public interface DubboBeanUtils {
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);
@@ -61,8 +58,10 @@ public interface DubboBeanUtils {
registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME,
DubboBootstrapApplicationListener.class);
- // Since 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean
- registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
- DubboConfigDefaultPropertyValueBeanPostProcessor.class);
+ // Since 2.7.9 Register DubboConfigBeanPostProcessor as an infrastructure Bean,
+ // merge processing logics of all DubboConfigAliasPostProcessor, DubboConfigDefaultPropertyValueBeanPostProcessor
+ // and DubboConfigEarlyInitializationPostProcessor
+ registerInfrastructureBean(registry, DubboConfigBeanPostProcessor.BEAN_NAME,
+ DubboConfigBeanPostProcessor.class);
}
}