You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/07/10 04:14:43 UTC
[dubbo] branch 3.0 updated: [3.0] Improve dubbo config beans and
bootstrap initialization (#8168)
This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new e321324 [3.0] Improve dubbo config beans and bootstrap initialization (#8168)
e321324 is described below
commit e3213249cec4a464e5ee47218514fbb2ada828d4
Author: Gong Dewei <ky...@qq.com>
AuthorDate: Sat Jul 10 12:14:33 2021 +0800
[3.0] Improve dubbo config beans and bootstrap initialization (#8168)
* Improve dubbo bootstrap initialization
* Initialize dubbo config beans before spring singleton beans
* add RAT
* Remove @PostConstruct method from AbstractConfig, register config beans in DubboConfigBeanInitializer
* fix tests
---
.../org/apache/dubbo/config/AbstractConfig.java | 15 ---
.../java/org/apache/dubbo/config/MethodConfig.java | 6 -
.../apache/dubbo/config/spring/ReferenceBean.java | 5 +-
.../ReferenceAnnotationBeanPostProcessor.java | 4 +
.../context/DubboBootstrapApplicationListener.java | 53 ++++++++-
.../spring/context/DubboConfigBeanInitializer.java | 110 +++++++++++++++++
.../DubboConfigInitializationPostProcessor.java | 131 ---------------------
.../context/event/DubboAnnotationInitedEvent.java | 37 ++++++
.../spring/reference/ReferenceBeanManager.java | 2 +-
.../dubbo/config/spring/util/DubboBeanUtils.java | 6 +-
.../reference/DubboConfigBeanInitializerTest.java | 117 ++++++++++++++++++
11 files changed, 324 insertions(+), 162 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 0f5a4b2..5b8c4e1 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
@@ -28,12 +28,10 @@ import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.MethodUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.AsyncMethodInfo;
-import javax.annotation.PostConstruct;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
@@ -639,19 +637,6 @@ public abstract class AbstractConfig implements Serializable {
this.isDefault = isDefault;
}
- /**
- * Add {@link AbstractConfig instance} into {@link ConfigManager}
- * <p>
- * Current method will invoked by Spring or Java EE container automatically, or should be triggered manually.
- *
- * @see ConfigManager#addConfig(AbstractConfig)
- * @since 2.7.5
- */
- @PostConstruct
- public void addIntoConfigManager() {
- ApplicationModel.getConfigManager().addConfig(this);
- }
-
@Override
public String toString() {
try {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
index a874216..8dde37b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
@@ -277,12 +277,6 @@ public class MethodConfig extends AbstractMethodConfig {
}
}
- @Override
- public void addIntoConfigManager() {
- // Don't add MethodConfig to ConfigManager
- // super.addIntoConfigManager();
- }
-
@Parameter(excluded = true)
public String getName() {
return name;
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 9220c6b..5bb21a2 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
@@ -20,6 +20,7 @@ import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport;
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
@@ -172,11 +173,11 @@ public class ReferenceBean<T> implements FactoryBean,
* In this way, the influence of Spring is eliminated, and the dubbo configuration initialization is controllable.
*
* <p/>
- * Dubbo config beans are initialized in DubboConfigInitializationPostProcessor.
+ * Dubbo config beans are initialized in DubboConfigBeanInitializer.
* <br/>
* The actual references will be processing in DubboBootstrap.referServices().
*
- * @see org.apache.dubbo.config.spring.context.DubboConfigInitializationPostProcessor
+ * @see DubboConfigBeanInitializer
* @see org.apache.dubbo.config.bootstrap.DubboBootstrap
*/
@Override
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index 5b2df1c..e8de74f 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -25,6 +25,7 @@ import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.spring.Constants;
+import org.apache.dubbo.config.spring.context.event.DubboAnnotationInitedEvent;
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
@@ -158,6 +159,9 @@ 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);
+
+ // this is an early event, it will be notified at org.springframework.context.support.AbstractApplicationContext.registerListeners()
+ applicationContext.publishEvent(new DubboAnnotationInitedEvent(applicationContext));
}
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java
index f40e663..6be80b3 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboBootstrapApplicationListener.java
@@ -20,21 +20,26 @@ import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.config.bootstrap.BootstrapTakeoverMode;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import com.alibaba.spring.context.OnceApplicationContextEventListener;
+import org.apache.dubbo.config.spring.context.event.DubboAnnotationInitedEvent;
+import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
+import static org.springframework.util.ObjectUtils.nullSafeEquals;
+
/**
* The {@link ApplicationListener} for {@link DubboBootstrap}'s lifecycle when the {@link ContextRefreshedEvent}
* and {@link ContextClosedEvent} raised
*
* @since 2.7.5
*/
-public class DubboBootstrapApplicationListener extends OnceApplicationContextEventListener implements Ordered {
+public class DubboBootstrapApplicationListener implements ApplicationListener, ApplicationContextAware, Ordered {
/**
* The bean name of {@link DubboBootstrapApplicationListener}
@@ -44,13 +49,13 @@ public class DubboBootstrapApplicationListener extends OnceApplicationContextEve
public static final String BEAN_NAME = "dubboBootstrapApplicationListener";
private final DubboBootstrap dubboBootstrap;
+ private ApplicationContext applicationContext;
public DubboBootstrapApplicationListener() {
this.dubboBootstrap = initBootstrap();
}
public DubboBootstrapApplicationListener(ApplicationContext applicationContext) {
- super(applicationContext);
this.dubboBootstrap = initBootstrap();
DubboBootstrapStartStopListenerSpringAdapter.applicationContext = applicationContext;
}
@@ -64,7 +69,38 @@ public class DubboBootstrapApplicationListener extends OnceApplicationContextEve
}
@Override
- public void onApplicationContextEvent(ApplicationContextEvent event) {
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (isOriginalEventSource(event)) {
+ if (event instanceof DubboAnnotationInitedEvent) {
+ // This event will be notified at AbstractApplicationContext.registerListeners(),
+ // init dubbo config beans before spring singleton beans
+ applicationContext.getBean(DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);
+
+ // All infrastructure config beans are loaded, initialize dubbo here
+ DubboBootstrap.getInstance().initialize();
+ } else if (event instanceof ApplicationContextEvent) {
+ this.onApplicationContextEvent((ApplicationContextEvent) event);
+ }
+ }
+ }
+
+ /**
+ * Is original {@link ApplicationContext} as the event source
+ * @param event {@link ApplicationEvent}
+ * @return if original, return <code>true</code>, or <code>false</code>
+ */
+ private boolean isOriginalEventSource(ApplicationEvent event) {
+
+ boolean originalEventSource = nullSafeEquals(getApplicationContext(), event.getSource());
+// if (!originalEventSource) {
+// if (log.isDebugEnabled()) {
+// log.debug("The source of event[" + event.getSource() + "] is not original!");
+// }
+// }
+ return originalEventSource;
+ }
+
+ private void onApplicationContextEvent(ApplicationContextEvent event) {
if (DubboBootstrapStartStopListenerSpringAdapter.applicationContext == null) {
DubboBootstrapStartStopListenerSpringAdapter.applicationContext = event.getApplicationContext();
}
@@ -91,4 +127,13 @@ public class DubboBootstrapApplicationListener extends OnceApplicationContextEve
public int getOrder() {
return LOWEST_PRECEDENCE;
}
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ public ApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigBeanInitializer.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigBeanInitializer.java
new file mode 100644
index 0000000..a56133b
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigBeanInitializer.java
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+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.context.ConfigManager;
+import org.apache.dubbo.config.spring.ConfigCenterBean;
+import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+/**
+ *
+ * Dubbo config bean initializer.
+ *
+ * NOTE: Dubbo config beans MUST be initialized after registering all BeanPostProcessors,
+ * that is after the AbstractApplicationContext#registerBeanPostProcessors() method.
+ */
+public class DubboConfigBeanInitializer implements BeanFactoryAware, InitializingBean {
+
+ public static String BEAN_NAME = "dubboConfigBeanInitializer";
+
+ private AtomicBoolean initialized = new AtomicBoolean(false);
+ private ConfigurableListableBeanFactory beanFactory;
+ private ReferenceBeanManager referenceBeanManager;
+ private ConfigManager configManager;
+
+ @Override
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ init();
+ }
+
+ private void init() {
+ if (initialized.compareAndSet(false, true)) {
+ configManager = ApplicationModel.getConfigManager();
+ referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
+ try {
+ prepareDubboConfigBeans();
+ referenceBeanManager.prepareReferenceBeans();
+ } catch (Throwable e) {
+ throw new FatalBeanException("Initialization dubbo config beans failed", e);
+ }
+ }
+ }
+
+ /**
+ * Initializes there Dubbo's Config Beans before @Reference bean autowiring
+ */
+ private void prepareDubboConfigBeans() {
+ //Make sure all these config beans are inited and registered to ConfigManager
+ loadConfigBeansOfType(ApplicationConfig.class);
+ loadConfigBeansOfType(ModuleConfig.class);
+ loadConfigBeansOfType(RegistryConfig.class);
+ loadConfigBeansOfType(ProtocolConfig.class);
+ loadConfigBeansOfType(MonitorConfig.class);
+ loadConfigBeansOfType(ProviderConfig.class);
+ loadConfigBeansOfType(ConsumerConfig.class);
+ loadConfigBeansOfType(ConfigCenterBean.class);
+ loadConfigBeansOfType(MetadataReportConfig.class);
+ loadConfigBeansOfType(MetricsConfig.class);
+ loadConfigBeansOfType(SslConfig.class);
+ }
+
+ private void loadConfigBeansOfType(Class<? extends AbstractConfig> configClass) {
+ String[] beanNames = beanFactory.getBeanNamesForType(configClass, true, false);
+ for (String beanName : beanNames) {
+ AbstractConfig configBean = beanFactory.getBean(beanName, configClass);
+ // Register config bean here, avoid relying on unreliable @PostConstruct init method
+ configManager.addConfig(configBean);
+ }
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigInitializationPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigInitializationPostProcessor.java
deleted file mode 100644
index de0a23f..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigInitializationPostProcessor.java
+++ /dev/null
@@ -1,131 +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;
-
-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.config.spring.reference.ReferenceBeanManager;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.Ordered;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
-
-/**
- *
- * Post-processor Dubbo config bean initialization.
- *
- * NOTE: Dubbo config beans MUST be initialized after registering all BeanPostProcessors,
- * that is after the AbstractApplicationContext#registerBeanPostProcessors() method.
- */
-public class DubboConfigInitializationPostProcessor implements BeanPostProcessor, BeanFactoryAware, ApplicationContextAware, Ordered {
-
- public static String BEAN_NAME = "dubboConfigInitializationPostProcessor";
-
- /**
- * This bean post processor should run before seata GlobalTransactionScanner(1024)
- */
- @Value("${dubbo.config-initialization-post-processor.order:1000}")
- private int order = 1000;
-
- private AtomicBoolean initialized = new AtomicBoolean(false);
- private ConfigurableListableBeanFactory beanFactory;
- private ReferenceBeanManager referenceBeanManager;
- private ApplicationContext applicationContext;
-
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (initialized.compareAndSet(false, true)) {
- try {
- prepareDubboConfigBeans(beanFactory);
- prepareReferenceBeans(beanFactory);
- } catch (Throwable e) {
- throw new FatalBeanException("Initialization dubbo config beans failed", e);
- }
- }
- return bean;
- }
-
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
-
- @Override
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
- referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
- }
-
- @Override
- public int getOrder() {
- return order;
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
- private void prepareReferenceBeans(ConfigurableListableBeanFactory beanFactory) throws Exception {
- referenceBeanManager.prepareReferenceBeans();
- }
-
- /**
- * Initializes there Dubbo's Config Beans before @Reference bean autowiring
- */
- private void prepareDubboConfigBeans(ConfigurableListableBeanFactory beanFactory) {
- //Make sure all these config beans are inited and registered to ConfigManager
- beansOfTypeIncludingAncestors(beanFactory, ApplicationConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, ModuleConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, RegistryConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, ProtocolConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, MonitorConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, ProviderConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, ConsumerConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, ConfigCenterBean.class);
- beansOfTypeIncludingAncestors(beanFactory, MetadataReportConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, MetricsConfig.class);
- beansOfTypeIncludingAncestors(beanFactory, SslConfig.class);
-
- //SHOULD NOT init service beans here, all BeanPostProcessors have not been loaded yet,
- //seata is not loaded, so the ServiceBean cannot be processed by seata
- //beansOfTypeIncludingAncestors(beanFactory, ServiceBean.class);
- }
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboAnnotationInitedEvent.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboAnnotationInitedEvent.java
new file mode 100644
index 0000000..1295f04
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboAnnotationInitedEvent.java
@@ -0,0 +1,37 @@
+/*
+ * 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.event;
+
+import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * An {@link ApplicationEvent} after Dubbo service/reference annotation has been processed.
+ * <p />
+ * NOTE: This event is used to trigger init {@link DubboConfigBeanInitializer}
+ */
+public class DubboAnnotationInitedEvent extends ApplicationEvent {
+ /**
+ * Create a new {@code ApplicationEvent}.
+ *
+ * @param source the object on which the event initially occurred or with
+ * which the event is associated (never {@code null})
+ */
+ public DubboAnnotationInitedEvent(Object source) {
+ super(source);
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanManager.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanManager.java
index e5b04aa..c87a068 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanManager.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanManager.java
@@ -60,7 +60,7 @@ public class ReferenceBeanManager implements ApplicationContextAware {
if (!initialized) {
//TODO add issue url to describe early initialization
- logger.warn("Early initialize reference bean before DubboConfigInitializationPostProcessor," +
+ logger.warn("Early initialize reference bean before DubboConfigBeanInitializer," +
" the BeanPostProcessor has not been loaded at this time, which may cause abnormalities in some components (such as seata): " +
referenceBeanName + " = " + ReferenceBeanSupport.generateReferenceKey(referenceBean, applicationContext));
}
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 61765e8..169af09 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
@@ -19,7 +19,7 @@ package org.apache.dubbo.config.spring.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServicePackagesHolder;
-import org.apache.dubbo.config.spring.context.DubboConfigInitializationPostProcessor;
+import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigAliasPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
@@ -80,8 +80,8 @@ public interface DubboBeanUtils {
registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
DubboConfigDefaultPropertyValueBeanPostProcessor.class);
- // Dubbo config initialization processor
- registerInfrastructureBean(registry, DubboConfigInitializationPostProcessor.BEAN_NAME, DubboConfigInitializationPostProcessor.class);
+ // Dubbo config initializer
+ registerInfrastructureBean(registry, DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);
// register infra bean if not exists later
registerInfrastructureBean(registry, DubboInfraBeanRegisterPostProcessor.BEAN_NAME, DubboInfraBeanRegisterPostProcessor.class);
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
new file mode 100644
index 0000000..0d3fe0c
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/DubboConfigBeanInitializerTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.reference;
+
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.config.spring.ZooKeeperServer;
+import org.apache.dubbo.config.spring.api.HelloService;
+import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
+import org.apache.dubbo.config.spring.context.annotation.provider.ProviderConfiguration;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for {@link org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer}
+ */
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(
+ classes = {
+ DubboConfigBeanInitializerTest.class,
+ DubboConfigBeanInitializerTest.AppConfiguration.class,
+ })
+@TestPropertySource(properties = {
+ "dubbo.protocol.port=-1",
+ "dubbo.registry.address=zookeeper://127.0.0.1:2181"
+})
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+public class DubboConfigBeanInitializerTest {
+
+ @BeforeAll
+ public static void beforeAll() {
+ ZooKeeperServer.start();
+ }
+
+ @Autowired
+ private FooService fooService;
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Test
+ public void test() {
+ Assertions.assertNotNull(fooService, "fooService is null");
+ Assertions.assertNotNull(fooService.helloService, "ooService.helloService is null");
+
+ // expect fooService is registered before dubbo config bean
+ List<String> beanNames = Arrays.asList(applicationContext.getBeanDefinitionNames());
+ int fooServiceIndex = beanNames.indexOf("fooService");
+ int applicationConfigIndex = beanNames.indexOf("dubbo-demo-application");
+ int registryConfigIndex = beanNames.indexOf("my-registry");
+ int configInitializerIndex = beanNames.indexOf(DubboConfigBeanInitializer.BEAN_NAME);
+ Assertions.assertTrue(fooServiceIndex < applicationConfigIndex);
+ Assertions.assertTrue(fooServiceIndex < registryConfigIndex);
+ Assertions.assertTrue(fooServiceIndex < configInitializerIndex);
+ }
+
+ @Configuration
+ // Import BusinessConfig first, make sure FooService bean is register early,
+ // expect dubbo config beans are initialized before FooService bean
+ @Import({BusinessConfig.class, ConsumerConfig.class, ProviderConfiguration.class})
+ static class AppConfiguration {
+
+ }
+
+ @Configuration
+ static class BusinessConfig {
+ @Bean
+ public FooService fooService() {
+ // DubboBootstrap should be inited at DubboConfigInitializer, before init FooService bean
+ Assertions.assertTrue(DubboBootstrap.getInstance().isInitialized());
+ return new FooService();
+ }
+ }
+
+ @Configuration
+ static class ConsumerConfig {
+ @DubboReference
+ private HelloService helloService;
+ }
+
+ static class FooService {
+ @Autowired
+ private HelloService helloService;
+ }
+}