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