You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by ky...@apache.org on 2021/08/20 19:04:57 UTC

[dubbo] branch 3.0-multi-instances updated: Support scoped injection for extension

This is an automated email from the ASF dual-hosted git repository.

kylixs pushed a commit to branch 3.0-multi-instances
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0-multi-instances by this push:
     new 7091d97  Support scoped injection for extension
7091d97 is described below

commit 7091d9782daeda69c8012d83888a65073124a98f
Author: gongdewei <ky...@qq.com>
AuthorDate: Sat Aug 21 03:04:10 2021 +0800

    Support scoped injection for extension
---
 .../dubbo/common/extension/ExtensionDirector.java  |  18 +-
 .../common/extension/ExtensionDirectorAware.java}  |  11 +-
 .../dubbo/common/extension/ExtensionInjector.java  |   7 +-
 .../dubbo/common/extension/ExtensionLoader.java    |   4 +
 .../dubbo/common/extension/ExtensionScope.java     |   7 +-
 .../AdaptiveExtensionInjector.java                 |  36 +++-
 .../{factory => inject}/SpiExtensionInjector.java  |  15 +-
 .../apache/dubbo/rpc/model/ApplicationModel.java   |  16 ++
 .../org/apache/dubbo/rpc/model/FrameworkModel.java |  22 +++
 .../org/apache/dubbo/rpc/model/ModuleModel.java    |   1 +
 ...apache.dubbo.common.extension.ExtensionInjector |   4 +-
 .../common/extension/ExtensionDirectorTest.java    | 181 ++++++++++++++++++---
 ...ApplicationService.java => FooAppProvider.java} |   7 +-
 ...{ApplicationService.java => FooAppService.java} |   7 +-
 ...eworkService.java => FooFrameworkProvider.java} |   7 +-
 ...meworkService.java => FooFrameworkService.java} |   7 +-
 .../{ModuleService.java => FooModuleProvider.java} |   7 +-
 .../{ModuleService.java => FooModuleService.java}  |   7 +-
 ...tFrameworkService.java => TestAppProvider.java} |   8 +-
 .../extension/director/impl/TestAppService.java    |  72 ++++++++
 ...workService.java => TestFrameworkProvider.java} |   8 +-
 .../director/impl/TestFrameworkService.java        |  42 ++++-
 ...icationService.java => TestModuleProvider.java} |  10 +-
 .../extension/director/impl/TestModuleService.java |  65 +++++++-
 ....dubbo.common.extension.director.FooAppProvider |   1 +
 ....dubbo.common.extension.director.FooAppService} |   2 +-
 ....common.extension.director.FooFrameworkProvider |   1 +
 ....common.extension.director.FooFrameworkService} |   0
 ...bbo.common.extension.director.FooModuleProvider |   1 +
 ...bbo.common.extension.director.FooModuleService} |   0
 .../bootstrap/DubboBootstrapMultiInstanceTest.java |  64 ++++++++
 .../spring/extension/SpringExtensionInjector.java  |   4 -
 .../META-INF/native-image/reflect-config.json      |   4 +-
 .../META-INF/native-image/reflect-config.json      |   4 +-
 34 files changed, 577 insertions(+), 73 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java
index ae686fd..76e9d99 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java
@@ -80,6 +80,14 @@ public class ExtensionDirector {
         // 1. find in local cache
         ExtensionLoader<T> loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);
 
+        final SPI annotation = type.getAnnotation(SPI.class);
+        ExtensionScope scope = annotation.scope();
+
+        if (loader == null && scope == ExtensionScope.SELF) {
+            // create an instance in self scope
+            loader = createExtensionLoader0(type);
+        }
+
         // 2. find in parent
         if (loader == null) {
             if (this.parent != null) {
@@ -99,8 +107,7 @@ public class ExtensionDirector {
         ExtensionLoader<T> loader = null;
         if (isScopeMatched(type)) {
             // if scope is matched, just create it
-            extensionLoadersMap.putIfAbsent(type, new ExtensionLoader<T>(type, this));
-            loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);
+            loader = createExtensionLoader0(type);
         } else {
             // if scope is not matched, redirect to parent director
             if (this.parent != null) {
@@ -110,6 +117,13 @@ public class ExtensionDirector {
         return loader;
     }
 
+    private <T> ExtensionLoader<T> createExtensionLoader0(Class<T> type) {
+        ExtensionLoader<T> loader;
+        extensionLoadersMap.putIfAbsent(type, new ExtensionLoader<T>(type, this));
+        loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);
+        return loader;
+    }
+
     private boolean isScopeMatched(Class<?> type) {
         final SPI defaultAnnotation = type.getAnnotation(SPI.class);
         return defaultAnnotation.scope().equals(scope);
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirectorAware.java
similarity index 74%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
copy to dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirectorAware.java
index c0dff97..5a68218 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirectorAware.java
@@ -14,12 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.extension.director;
+package org.apache.dubbo.common.extension;
 
-import org.apache.dubbo.common.extension.ExtensionScope;
-import org.apache.dubbo.common.extension.SPI;
+/**
+ * SPI extension can implement this aware interface to obtain appropriate {@link ExtensionDirector} instance.
+ */
+public interface ExtensionDirectorAware {
 
-@SPI(scope = ExtensionScope.APPLICATION)
-public interface ApplicationService {
+    void setExtensionDirector(ExtensionDirector extensionDirector);
 
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionInjector.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionInjector.java
index c550645..0af3cbb 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionInjector.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionInjector.java
@@ -19,8 +19,8 @@ package org.apache.dubbo.common.extension;
 /**
  * An injector to provide resources for SPI extension.
  */
-@SPI(scope = ExtensionScope.FRAMEWORK)
-public interface ExtensionInjector {
+@SPI(scope = ExtensionScope.SELF)
+public interface ExtensionInjector extends ExtensionDirectorAware {
 
     /**
      * Get instance of specify type and name.
@@ -31,4 +31,7 @@ public interface ExtensionInjector {
      */
     <T> T getInstance(Class<T> type, String name);
 
+    @Override
+    default void setExtensionDirector(ExtensionDirector extensionDirector) {
+    }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index feae2d4..a7ef06f 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -734,6 +734,9 @@ public class ExtensionLoader<T> {
     }
 
     private T postProcessAfterInitialization(T instance, String name) throws Exception {
+        if (instance instanceof ExtensionDirectorAware) {
+            ((ExtensionDirectorAware) instance).setExtensionDirector(extensionDirector);
+        }
         if (extensionPostProcessors != null) {
             for (ExtensionPostProcessor processor : extensionPostProcessors) {
                 instance = (T) processor.postProcessAfterInitialization(instance, name);
@@ -1114,6 +1117,7 @@ public class ExtensionLoader<T> {
             instance = postProcessBeforeInitialization(instance, null);
             instance = injectExtension(instance);
             instance = postProcessAfterInitialization(instance, null);
+            initExtension(instance);
             return instance;
         } catch (Exception e) {
             throw new IllegalStateException("Can't create adaptive extension " + type + ", cause: " + e.getMessage(), e);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionScope.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionScope.java
index 7f32bf6..170a9c0 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionScope.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionScope.java
@@ -69,5 +69,10 @@ public enum ExtensionScope {
      * <li>Isolate extension data in different modules inside application</li>
      * </ol>
      */
-    MODULE
+    MODULE,
+
+    /**
+     * self-sufficient, creates an instance for per scope, for special SPI extension, like {@link ExtensionInjector}
+     */
+    SELF
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/AdaptiveExtensionInjector.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/AdaptiveExtensionInjector.java
similarity index 62%
rename from dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/AdaptiveExtensionInjector.java
rename to dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/AdaptiveExtensionInjector.java
index 8c76f50..3c78474 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/AdaptiveExtensionInjector.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/AdaptiveExtensionInjector.java
@@ -14,9 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.extension.factory;
+package org.apache.dubbo.common.extension.inject;
 
+import org.apache.dubbo.common.context.Lifecycle;
 import org.apache.dubbo.common.extension.Adaptive;
+import org.apache.dubbo.common.extension.ExtensionDirector;
 import org.apache.dubbo.common.extension.ExtensionInjector;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 
@@ -28,23 +30,34 @@ import java.util.List;
  * AdaptiveExtensionInjector
  */
 @Adaptive
-public class AdaptiveExtensionInjector implements ExtensionInjector {
+public class AdaptiveExtensionInjector implements ExtensionInjector, Lifecycle {
 
-    private final List<ExtensionInjector> factories;
+    private List<ExtensionInjector> injectors = Collections.emptyList();
+
+    private ExtensionDirector extensionDirector;
 
     public AdaptiveExtensionInjector() {
-        ExtensionLoader<ExtensionInjector> loader = ExtensionLoader.getExtensionLoader(ExtensionInjector.class);
+    }
+
+    @Override
+    public void setExtensionDirector(ExtensionDirector extensionDirector) {
+        this.extensionDirector = extensionDirector;
+    }
+
+    @Override
+    public void initialize() throws IllegalStateException {
+        ExtensionLoader<ExtensionInjector> loader = extensionDirector.getExtensionLoader(ExtensionInjector.class);
         List<ExtensionInjector> list = new ArrayList<ExtensionInjector>();
         for (String name : loader.getSupportedExtensions()) {
             list.add(loader.getExtension(name));
         }
-        factories = Collections.unmodifiableList(list);
+        injectors = Collections.unmodifiableList(list);
     }
 
     @Override
     public <T> T getInstance(Class<T> type, String name) {
-        for (ExtensionInjector factory : factories) {
-            T extension = factory.getInstance(type, name);
+        for (ExtensionInjector injector : injectors) {
+            T extension = injector.getInstance(type, name);
             if (extension != null) {
                 return extension;
             }
@@ -52,4 +65,13 @@ public class AdaptiveExtensionInjector implements ExtensionInjector {
         return null;
     }
 
+    @Override
+    public void start() throws IllegalStateException {
+
+    }
+
+    @Override
+    public void destroy() throws IllegalStateException {
+
+    }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/SpiExtensionInjector.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/SpiExtensionInjector.java
similarity index 74%
rename from dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/SpiExtensionInjector.java
rename to dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/SpiExtensionInjector.java
index 746e3ce..1ee4d71 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/factory/SpiExtensionInjector.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/inject/SpiExtensionInjector.java
@@ -14,8 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.extension.factory;
+package org.apache.dubbo.common.extension.inject;
 
+import org.apache.dubbo.common.extension.ExtensionDirector;
 import org.apache.dubbo.common.extension.ExtensionInjector;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.extension.SPI;
@@ -25,10 +26,20 @@ import org.apache.dubbo.common.extension.SPI;
  */
 public class SpiExtensionInjector implements ExtensionInjector {
 
+    private ExtensionDirector extensionDirector;
+
+    @Override
+    public void setExtensionDirector(ExtensionDirector extensionDirector) {
+        this.extensionDirector = extensionDirector;
+    }
+
     @Override
     public <T> T getInstance(Class<T> type, String name) {
         if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
-            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
+            ExtensionLoader<T> loader = extensionDirector.getExtensionLoader(type);
+            if (loader == null) {
+                return null;
+            }
             if (!loader.getSupportedExtensions().isEmpty()) {
                 return loader.getAdaptiveExtension();
             }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
index f48d237..4954ea0 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
@@ -28,6 +28,8 @@ import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.context.ConfigManager;
 
 import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -50,6 +52,7 @@ public class ApplicationModel {
     public static final String NAME = "application";
     private static volatile ApplicationModel defaultInstance;
 
+    private Collection<ModuleModel> moduleModels = Collections.synchronizedSet(new LinkedHashSet<>());
     private AtomicBoolean initFlag = new AtomicBoolean(false);
     private Environment environment;
     private ConfigManager configManager;
@@ -62,6 +65,7 @@ public class ApplicationModel {
         this.frameworkModel = frameworkModel;
         extensionDirector = new ExtensionDirector(frameworkModel.getExtensionDirector(), ExtensionScope.APPLICATION);
         extensionDirector.addExtensionPostProcessor(new ModelAwarePostProcessor(this));
+        frameworkModel.addApplication(this);
     }
 
     public static ApplicationModel defaultModel() {
@@ -160,6 +164,18 @@ public class ApplicationModel {
         return getApplicationConfig().getName();
     }
 
+    public void addModule(ModuleModel model) {
+        this.moduleModels.add(model);
+    }
+
+    public void removeModule(ModuleModel model) {
+        this.moduleModels.remove(model);
+    }
+
+    public Collection<ModuleModel> getModuleModels() {
+        return moduleModels;
+    }
+
     // only for unit test
     @Deprecated
     public static void reset() {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java
index 1a6a07f..18cc148 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java
@@ -19,16 +19,26 @@ package org.apache.dubbo.rpc.model;
 import org.apache.dubbo.common.extension.ExtensionDirector;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.extension.ExtensionScope;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
 
 /**
  * Model of dubbo framework, it can be shared with multiple applications.
  */
 public class FrameworkModel {
 
+    protected static final Logger LOGGER = LoggerFactory.getLogger(FrameworkModel.class);
+
     private volatile static FrameworkModel defaultInstance;
 
     private final ExtensionDirector extensionDirector;
 
+    private Collection<ApplicationModel> applicationModels = Collections.synchronizedSet(new LinkedHashSet<>());
+
     public FrameworkModel() {
         extensionDirector = new ExtensionDirector(null, ExtensionScope.FRAMEWORK);
         extensionDirector.addExtensionPostProcessor(new ModelAwarePostProcessor(this));
@@ -52,4 +62,16 @@ public class FrameworkModel {
     public <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
         return extensionDirector.getExtensionLoader(type);
     }
+
+    public void addApplication(ApplicationModel model) {
+        this.applicationModels.add(model);
+    }
+
+    public void removeApplication(ApplicationModel model) {
+        this.applicationModels.remove(model);
+    }
+
+    public Collection<ApplicationModel> getApplicationModels() {
+        return applicationModels;
+    }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java
index f0f68de..e2e8345 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java
@@ -32,6 +32,7 @@ public class ModuleModel {
         this.applicationModel = applicationModel;
         extensionDirector = new ExtensionDirector(applicationModel.getExtensionDirector(), ExtensionScope.MODULE);
         extensionDirector.addExtensionPostProcessor(new ModelAwarePostProcessor(this));
+        applicationModel.addModule(this);
     }
 
     public ApplicationModel getApplicationModel() {
diff --git a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector
index 3a4e291..d524580 100644
--- a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector
+++ b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector
@@ -1,2 +1,2 @@
-adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionInjector
-spi=org.apache.dubbo.common.extension.factory.SpiExtensionInjector
+adaptive=org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector
+spi=org.apache.dubbo.common.extension.inject.SpiExtensionInjector
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java
index 1c09a53..f2d4030 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java
@@ -16,12 +16,11 @@
  */
 package org.apache.dubbo.common.extension;
 
-import org.apache.dubbo.common.extension.ExtensionDirector;
-import org.apache.dubbo.common.extension.ExtensionScope;
-import org.apache.dubbo.common.extension.director.ApplicationService;
-import org.apache.dubbo.common.extension.director.FrameworkService;
-import org.apache.dubbo.common.extension.director.ModuleService;
-import org.apache.dubbo.common.extension.director.impl.TestApplicationService;
+import org.apache.dubbo.common.extension.director.FooAppService;
+import org.apache.dubbo.common.extension.director.FooFrameworkService;
+import org.apache.dubbo.common.extension.director.FooModuleProvider;
+import org.apache.dubbo.common.extension.director.FooModuleService;
+import org.apache.dubbo.common.extension.director.impl.TestAppService;
 import org.apache.dubbo.common.extension.director.impl.TestFrameworkService;
 import org.apache.dubbo.common.extension.director.impl.TestModuleService;
 import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -30,16 +29,22 @@ import org.apache.dubbo.rpc.model.ModuleModel;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.util.Collection;
+
 public class ExtensionDirectorTest {
 
     String testFwSrvName = "testFwSrv";
     String testAppSrvName = "testAppSrv";
     String testMdSrvName = "testMdSrv";
 
+    String testAppProviderName = "testAppProvider";
+    String testModuleProviderName = "testModuleProvider";
+    String testFrameworkProviderName = "testFrameworkProvider";
+
     @Test
     public void testInheritanceAndScope() {
 
-        // expecting:
+        // Expecting:
         // 1. SPI extension only be created in ExtensionDirector which matched scope
         // 2. Child ExtensionDirector can get extension instance from parent
         // 3. Parent ExtensionDirector can't get extension instance from child
@@ -49,27 +54,27 @@ public class ExtensionDirectorTest {
         ExtensionDirector moduleExtensionDirector = new ExtensionDirector(appExtensionDirector, ExtensionScope.MODULE);
 
         // test module extension loader
-        FrameworkService testFwSrvFromModule = moduleExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        ApplicationService testAppSrvFromModule = moduleExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        ModuleService testMdSrvFromModule = moduleExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        FooFrameworkService testFwSrvFromModule = moduleExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        FooAppService testAppSrvFromModule = moduleExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        FooModuleService testMdSrvFromModule = moduleExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertNotNull(testFwSrvFromModule);
         Assertions.assertNotNull(testAppSrvFromModule);
         Assertions.assertNotNull(testMdSrvFromModule);
 
         // test app extension loader
-        FrameworkService testFwSrvFromApp = appExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        ApplicationService testAppSrvFromApp = appExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        ModuleService testMdSrvFromApp = appExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        FooFrameworkService testFwSrvFromApp = appExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        FooAppService testAppSrvFromApp = appExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        FooModuleService testMdSrvFromApp = appExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertSame(testFwSrvFromApp, testFwSrvFromModule);
         Assertions.assertSame(testAppSrvFromApp, testAppSrvFromModule);
         Assertions.assertNull(testMdSrvFromApp);
 
         // test framework extension loader
-        FrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        ApplicationService testAppSrvFromFw = fwExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        ModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        FooFrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        FooAppService testAppSrvFromFw = fwExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        FooModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertSame(testFwSrvFromFw, testFwSrvFromApp);
         Assertions.assertNull(testAppSrvFromFw);
@@ -102,9 +107,9 @@ public class ExtensionDirectorTest {
         Assertions.assertSame(null, fwExtensionDirector.getParent());
 
         // check module extension aware
-        TestFrameworkService testFwSrvFromModule = (TestFrameworkService) moduleExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        TestApplicationService testAppSrvFromModule = (TestApplicationService) moduleExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        TestModuleService testMdSrvFromModule = (TestModuleService) moduleExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        TestFrameworkService testFwSrvFromModule = (TestFrameworkService) moduleExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        TestAppService testAppSrvFromModule = (TestAppService) moduleExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        TestModuleService testMdSrvFromModule = (TestModuleService) moduleExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertSame(frameworkModel, testFwSrvFromModule.getFrameworkModel());
         Assertions.assertSame(null, testFwSrvFromModule.getApplicationModel());
@@ -119,22 +124,148 @@ public class ExtensionDirectorTest {
         Assertions.assertSame(moduleModel, testMdSrvFromModule.getModuleModel());
 
         // check app extension aware
-        TestFrameworkService testFwSrvFromApp = (TestFrameworkService) appExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        TestApplicationService testAppSrvFromApp = (TestApplicationService) appExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        TestModuleService testMdSrvFromApp = (TestModuleService) appExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        TestFrameworkService testFwSrvFromApp = (TestFrameworkService) appExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        TestAppService testAppSrvFromApp = (TestAppService) appExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        TestModuleService testMdSrvFromApp = (TestModuleService) appExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertSame(testFwSrvFromApp, testFwSrvFromModule);
         Assertions.assertSame(testAppSrvFromApp, testAppSrvFromModule);
         Assertions.assertNull(testMdSrvFromApp);
 
         // check framework extension aware
-        FrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FrameworkService.class, testFwSrvName);
-        ApplicationService testAppSrvFromFw = fwExtensionDirector.getExtension(ApplicationService.class, testAppSrvName);
-        ModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(ModuleService.class, testMdSrvName);
+        FooFrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
+        FooAppService testAppSrvFromFw = fwExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
+        FooModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
 
         Assertions.assertSame(testFwSrvFromFw, testFwSrvFromApp);
         Assertions.assertNull(testAppSrvFromFw);
         Assertions.assertNull(testMdSrvFromFw);
+    }
+
+    @Test
+    public void testModelDataIsolation() {
+//Model Tree
+//├─frameworkModel1
+//│  ├─applicationModel11
+//│  │  ├─moduleModel111
+//│  │  └─moduleModel112
+//│  └─applicationModel12
+//│     └─moduleModel121
+//└─frameworkModel2
+//   └─applicationModel21
+//      └─moduleModel211
+
+        FrameworkModel frameworkModel1 = new FrameworkModel();
+        ApplicationModel applicationModel11 = new ApplicationModel(frameworkModel1);
+        ModuleModel moduleModel111 = new ModuleModel(applicationModel11);
+        ModuleModel moduleModel112 = new ModuleModel(applicationModel11);
+
+        ApplicationModel applicationModel12 = new ApplicationModel(frameworkModel1);
+        ModuleModel moduleModel121 = new ModuleModel(applicationModel12);
+
+        FrameworkModel frameworkModel2 = new FrameworkModel();
+        ApplicationModel applicationModel21 = new ApplicationModel(frameworkModel2);
+        ModuleModel moduleModel211 = new ModuleModel(applicationModel21);
+
+        // test model references
+        Collection<ApplicationModel> applicationsOfFw1 = frameworkModel1.getApplicationModels();
+        Assertions.assertEquals(2, applicationsOfFw1.size());
+        Assertions.assertTrue(applicationsOfFw1.contains(applicationModel11));
+        Assertions.assertTrue(applicationsOfFw1.contains(applicationModel12));
+        Assertions.assertFalse(applicationsOfFw1.contains(applicationModel21));
+
+        Collection<ModuleModel> modulesOfApp11 = applicationModel11.getModuleModels();
+        Assertions.assertEquals(2, modulesOfApp11.size());
+        Assertions.assertTrue(modulesOfApp11.contains(moduleModel111));
+        Assertions.assertTrue(modulesOfApp11.contains(moduleModel112));
+
+        // test isolation of FrameworkModel
+        FooFrameworkService frameworkService1 = frameworkModel1.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        FooFrameworkService frameworkService2 = frameworkModel2.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        Assertions.assertNotSame(frameworkService1, frameworkService2);
+
+        // test isolation of ApplicationModel
+        // applicationModel11 and applicationModel12 are shared frameworkModel1
+        FooFrameworkService frameworkService11 = applicationModel11.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        FooFrameworkService frameworkService12 = applicationModel12.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        Assertions.assertSame(frameworkService1, frameworkService11);
+        Assertions.assertSame(frameworkService1, frameworkService12);
+
+        // applicationModel11 and applicationModel12 are isolated in application scope
+        FooAppService applicationService11 = applicationModel11.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        FooAppService applicationService12 = applicationModel12.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        Assertions.assertNotSame(applicationService11, applicationService12);
+
+        // applicationModel11 and applicationModel21 are isolated in both framework and application scope
+        FooFrameworkService frameworkService21 = applicationModel21.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        FooAppService applicationService21 = applicationModel21.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        Assertions.assertNotSame(frameworkService11, frameworkService21);
+        Assertions.assertNotSame(applicationService11, applicationService21);
+
+        // test isolation of ModuleModel
+        FooModuleService moduleService111 = moduleModel111.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
+        FooModuleService moduleService112 = moduleModel112.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
+
+        // moduleModel111 and moduleModel112 are isolated in module scope
+        Assertions.assertNotSame(moduleService111, moduleService112);
+
+        // moduleModel111 and moduleModel112 are shared applicationModel11
+        FooAppService applicationService111 = moduleModel111.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        FooAppService applicationService112 = moduleModel112.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        Assertions.assertSame(applicationService111, applicationService112);
+
+        // moduleModel111 and moduleModel121 are isolated in application scope, but shared frameworkModel1
+        FooAppService applicationService121 = moduleModel121.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        Assertions.assertNotSame(applicationService111, applicationService121);
+
+        FooFrameworkService frameworkService111 = moduleModel111.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        FooFrameworkService frameworkService121 = moduleModel121.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        Assertions.assertSame(frameworkService111, frameworkService121);
+
+        // moduleModel111 and moduleModel211 are isolated in both framework and application scope
+        FooModuleService moduleService211 = moduleModel211.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
+        FooAppService applicationService211 = moduleModel211.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
+        FooFrameworkService frameworkService211 = moduleModel211.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
+        Assertions.assertNotSame(moduleService111, moduleService211);
+        Assertions.assertNotSame(applicationService111, applicationService211);
+        Assertions.assertNotSame(frameworkService111, frameworkService211);
+    }
+
+    @Test
+    public void testInjection() {
+
+        // Expect:
+        // 1. Framework scope extension can be injected to extensions of Framework/Application/Module scope
+        // 2. Application scope extension can be injected to extensions of Application/Module scope, but not Framework scope
+        // 3. Module scope extension can be injected to extensions of Module scope, but not Framework/Application scope
+
+        FrameworkModel frameworkModel = new FrameworkModel();
+        ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
+        ModuleModel moduleModel = new ModuleModel(applicationModel);
+
+        // check module service
+        TestModuleService moduleService = (TestModuleService) moduleModel.getExtensionDirector()
+            .getExtension(FooModuleService.class, testMdSrvName);
+        Assertions.assertNotNull(moduleService.getFrameworkService());
+        Assertions.assertNotNull(moduleService.getFrameworkProvider());
+        Assertions.assertNotNull(moduleService.getAppService());
+        Assertions.assertNotNull(moduleService.getAppProvider());
+        Assertions.assertNotNull(moduleService.getModuleProvider());
+
+        // check app service
+        TestAppService appService = (TestAppService) applicationModel.getExtensionDirector()
+            .getExtension(FooAppService.class, testAppSrvName);
+        Assertions.assertNotNull(appService.getFrameworkService());
+        Assertions.assertNotNull(appService.getFrameworkProvider());
+        Assertions.assertNotNull(appService.getAppProvider());
+        Assertions.assertNull(appService.getModuleProvider());
+
+        // check framework service
+        TestFrameworkService frameworkService = (TestFrameworkService) frameworkModel.getExtensionDirector()
+            .getExtension(FooFrameworkService.class, testFwSrvName);
+        Assertions.assertNotNull(frameworkService.getFrameworkProvider());
+        Assertions.assertNull(frameworkService.getAppProvider());
+        Assertions.assertNull(frameworkService.getModuleProvider());
 
     }
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppProvider.java
similarity index 86%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
copy to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppProvider.java
index c0dff97..e885271 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppProvider.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.APPLICATION)
-public interface ApplicationService {
+public interface FooAppProvider {
+
+    @Adaptive
+    void process(URL url);
 
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppService.java
similarity index 86%
rename from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppService.java
index c0dff97..d475092 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ApplicationService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooAppService.java
@@ -16,10 +16,13 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.APPLICATION)
-public interface ApplicationService {
-
+public interface FooAppService {
+    @Adaptive
+    void process(URL url);
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkProvider.java
similarity index 85%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java
copy to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkProvider.java
index 9703689..194c818 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkProvider.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.FRAMEWORK)
-public interface FrameworkService {
+public interface FooFrameworkProvider {
+
+    @Adaptive
+    void process(URL url);
 
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkService.java
similarity index 85%
rename from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkService.java
index 9703689..2ff1403 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FrameworkService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooFrameworkService.java
@@ -16,10 +16,13 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.FRAMEWORK)
-public interface FrameworkService {
-
+public interface FooFrameworkService {
+    @Adaptive
+    void process(URL url);
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleProvider.java
similarity index 85%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java
copy to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleProvider.java
index a9b940f..9d4b81e 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleProvider.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.MODULE)
-public interface ModuleService {
+public interface FooModuleProvider {
+
+    @Adaptive
+    void process(URL url);
 
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleService.java
similarity index 85%
rename from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleService.java
index a9b940f..87ce080 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/ModuleService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/FooModuleService.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.common.extension.director;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
 import org.apache.dubbo.common.extension.ExtensionScope;
 import org.apache.dubbo.common.extension.SPI;
 
 @SPI(scope = ExtensionScope.MODULE)
-public interface ModuleService {
+public interface FooModuleService {
+
+    @Adaptive
+    void process(URL url);
 
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppProvider.java
similarity index 80%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
copy to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppProvider.java
index 416ba0d..cf60246 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppProvider.java
@@ -16,8 +16,12 @@
  */
 package org.apache.dubbo.common.extension.director.impl;
 
-import org.apache.dubbo.common.extension.director.FrameworkService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooAppProvider;
 
-public class TestFrameworkService extends BaseTestService implements FrameworkService {
+public class TestAppProvider implements FooAppProvider {
+    @Override
+    public void process(URL url) {
 
+    }
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppService.java
new file mode 100644
index 0000000..ed5aec4
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestAppService.java
@@ -0,0 +1,72 @@
+/*
+ * 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.common.extension.director.impl;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooAppProvider;
+import org.apache.dubbo.common.extension.director.FooAppService;
+import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
+import org.apache.dubbo.common.extension.director.FooFrameworkService;
+import org.apache.dubbo.common.extension.director.FooModuleProvider;
+
+public class TestAppService extends BaseTestService implements FooAppService {
+
+    private FooFrameworkService frameworkService;
+
+    private FooFrameworkProvider frameworkProvider;
+
+    private FooAppProvider appProvider;
+
+    private FooModuleProvider moduleProvider;
+
+    public FooFrameworkService getFrameworkService() {
+        return frameworkService;
+    }
+
+    public void setFrameworkService(FooFrameworkService frameworkService) {
+        this.frameworkService = frameworkService;
+    }
+
+    public FooAppProvider getAppProvider() {
+        return appProvider;
+    }
+
+    public void setAppProvider(FooAppProvider appProvider) {
+        this.appProvider = appProvider;
+    }
+
+    public FooModuleProvider getModuleProvider() {
+        return moduleProvider;
+    }
+
+    public void setModuleProvider(FooModuleProvider moduleProvider) {
+        this.moduleProvider = moduleProvider;
+    }
+
+    public FooFrameworkProvider getFrameworkProvider() {
+        return frameworkProvider;
+    }
+
+    public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
+        this.frameworkProvider = frameworkProvider;
+    }
+
+    @Override
+    public void process(URL url) {
+
+    }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkProvider.java
similarity index 78%
copy from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
copy to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkProvider.java
index 416ba0d..25dcb66 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkProvider.java
@@ -16,8 +16,12 @@
  */
 package org.apache.dubbo.common.extension.director.impl;
 
-import org.apache.dubbo.common.extension.director.FrameworkService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
 
-public class TestFrameworkService extends BaseTestService implements FrameworkService {
+public class TestFrameworkProvider implements FooFrameworkProvider {
+    @Override
+    public void process(URL url) {
 
+    }
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
index 416ba0d..45b71b1 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestFrameworkService.java
@@ -16,8 +16,46 @@
  */
 package org.apache.dubbo.common.extension.director.impl;
 
-import org.apache.dubbo.common.extension.director.FrameworkService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooAppProvider;
+import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
+import org.apache.dubbo.common.extension.director.FooFrameworkService;
+import org.apache.dubbo.common.extension.director.FooModuleProvider;
 
-public class TestFrameworkService extends BaseTestService implements FrameworkService {
+public class TestFrameworkService extends BaseTestService implements FooFrameworkService {
 
+    private FooFrameworkProvider frameworkProvider;
+
+    private FooAppProvider appProvider;
+
+    private FooModuleProvider moduleProvider;
+
+    public FooFrameworkProvider getFrameworkProvider() {
+        return frameworkProvider;
+    }
+
+    public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
+        this.frameworkProvider = frameworkProvider;
+    }
+
+    public FooAppProvider getAppProvider() {
+        return appProvider;
+    }
+
+    public void setAppProvider(FooAppProvider appProvider) {
+        this.appProvider = appProvider;
+    }
+
+    public FooModuleProvider getModuleProvider() {
+        return moduleProvider;
+    }
+
+    public void setModuleProvider(FooModuleProvider moduleProvider) {
+        this.moduleProvider = moduleProvider;
+    }
+
+    @Override
+    public void process(URL url) {
+
+    }
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestApplicationService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleProvider.java
similarity index 80%
rename from dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestApplicationService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleProvider.java
index 9a0e1ef..604c291 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestApplicationService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleProvider.java
@@ -16,7 +16,13 @@
  */
 package org.apache.dubbo.common.extension.director.impl;
 
-import org.apache.dubbo.common.extension.director.ApplicationService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooModuleProvider;
+
+public class TestModuleProvider implements FooModuleProvider {
+
+    public void process(URL url) {
+
+    }
 
-public class TestApplicationService extends BaseTestService implements ApplicationService {
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleService.java
index afdbecb..d7c0ad7 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/TestModuleService.java
@@ -16,7 +16,68 @@
  */
 package org.apache.dubbo.common.extension.director.impl;
 
-import org.apache.dubbo.common.extension.director.ModuleService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.director.FooAppProvider;
+import org.apache.dubbo.common.extension.director.FooAppService;
+import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
+import org.apache.dubbo.common.extension.director.FooFrameworkService;
+import org.apache.dubbo.common.extension.director.FooModuleProvider;
+import org.apache.dubbo.common.extension.director.FooModuleService;
 
-public class TestModuleService extends BaseTestService implements ModuleService {
+public class TestModuleService extends BaseTestService implements FooModuleService {
+
+    private FooFrameworkService frameworkService;
+
+    private FooFrameworkProvider frameworkProvider;
+
+    private FooAppService appService;
+
+    private FooAppProvider appProvider;
+
+    private FooModuleProvider moduleProvider;
+
+    public FooFrameworkService getFrameworkService() {
+        return frameworkService;
+    }
+
+    public void setFrameworkService(FooFrameworkService frameworkService) {
+        this.frameworkService = frameworkService;
+    }
+
+    public FooAppProvider getAppProvider() {
+        return appProvider;
+    }
+
+    public void setAppProvider(FooAppProvider appProvider) {
+        this.appProvider = appProvider;
+    }
+
+    public FooModuleProvider getModuleProvider() {
+        return moduleProvider;
+    }
+
+    public void setModuleProvider(FooModuleProvider moduleProvider) {
+        this.moduleProvider = moduleProvider;
+    }
+
+    public FooFrameworkProvider getFrameworkProvider() {
+        return frameworkProvider;
+    }
+
+    public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
+        this.frameworkProvider = frameworkProvider;
+    }
+
+    public FooAppService getAppService() {
+        return appService;
+    }
+
+    public void setAppService(FooAppService appService) {
+        this.appService = appService;
+    }
+
+    @Override
+    public void process(URL url) {
+
+    }
 }
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppProvider b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppProvider
new file mode 100644
index 0000000..667a52d
--- /dev/null
+++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppProvider
@@ -0,0 +1 @@
+testAppProvider=org.apache.dubbo.common.extension.director.impl.TestAppProvider
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.ApplicationService b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppService
similarity index 78%
rename from dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.ApplicationService
rename to dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppService
index 10d253b..37fe7c3 100644
--- a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.ApplicationService
+++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooAppService
@@ -1 +1 @@
-testAppSrv=org.apache.dubbo.common.extension.director.impl.TestApplicationService
+testAppSrv=org.apache.dubbo.common.extension.director.impl.TestAppService
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooFrameworkProvider b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooFrameworkProvider
new file mode 100644
index 0000000..a1f9f61
--- /dev/null
+++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooFrameworkProvider
@@ -0,0 +1 @@
+testFrameworkProvider=org.apache.dubbo.common.extension.director.impl.TestFrameworkProvider
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FrameworkService b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooFrameworkService
similarity index 100%
rename from dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FrameworkService
rename to dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooFrameworkService
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooModuleProvider b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooModuleProvider
new file mode 100644
index 0000000..cfa3cd9
--- /dev/null
+++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooModuleProvider
@@ -0,0 +1 @@
+testModuleProvider=org.apache.dubbo.common.extension.director.impl.TestModuleProvider
diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.ModuleService b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooModuleService
similarity index 100%
rename from dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.ModuleService
rename to dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.extension.director.FooModuleService
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
new file mode 100644
index 0000000..858fb75
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapMultiInstanceTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.bootstrap;
+
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class DubboBootstrapMultiInstanceTest {
+
+    @Test
+    public void testIsolatedApplications() {
+
+        DubboBootstrap dubboBootstrap1 = DubboBootstrap.newInstance();
+        DubboBootstrap dubboBootstrap2 = DubboBootstrap.newInstance();
+        ApplicationModel applicationModel1 = dubboBootstrap1.getApplicationModel();
+        ApplicationModel applicationModel2 = dubboBootstrap2.getApplicationModel();
+        Assertions.assertNotSame(applicationModel1, applicationModel2);
+        Assertions.assertNotSame(applicationModel1.getFrameworkModel(), applicationModel2.getFrameworkModel());
+        Assertions.assertNotSame(dubboBootstrap1.getConfigManager(), dubboBootstrap2.getConfigManager());
+
+//        dubboBootstrap1.application("app1")
+//            .registry(registry1)
+//            .configCenter(configCenter1)
+//            .metadataReport(metadataReport1)
+//            .protocol(protocol1)
+//            .provider(provider1)
+//            .consumer(consumer1)
+//            .monitor(monitor1)
+//            .metrics(metrics1)
+//            .ssl(sslConfig1);
+//
+
+    }
+
+    @Test
+    public void testSharedApplications() {
+
+        FrameworkModel frameworkModel = new FrameworkModel();
+        DubboBootstrap dubboBootstrap1 = DubboBootstrap.newInstance(frameworkModel);
+        DubboBootstrap dubboBootstrap2 = DubboBootstrap.newInstance(frameworkModel);
+        ApplicationModel applicationModel1 = dubboBootstrap1.getApplicationModel();
+        ApplicationModel applicationModel2 = dubboBootstrap2.getApplicationModel();
+        Assertions.assertNotSame(applicationModel1, applicationModel2);
+        Assertions.assertSame(applicationModel1.getFrameworkModel(), applicationModel2.getFrameworkModel());
+        Assertions.assertNotSame(dubboBootstrap1.getConfigManager(), dubboBootstrap2.getConfigManager());
+
+    }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java
index 09bf0dd..c580ab2 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java
@@ -47,10 +47,6 @@ public class SpringExtensionInjector implements ExtensionInjector, Lifecycle {
         }
     }
 
-    public static void removeApplicationContext(ApplicationContext context) {
-        CONTEXTS.remove(context);
-    }
-
     public static Set<ApplicationContext> getContexts() {
         return CONTEXTS;
     }
diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json
index 2aeba37..e558b5d 100644
--- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json
+++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json
@@ -340,11 +340,11 @@
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {
-  "name":"org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory",
+  "name":"org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector",
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {
-  "name":"org.apache.dubbo.common.extension.factory.SpiExtensionFactory",
+  "name":"org.apache.dubbo.common.extension.inject.SpiExtensionInjector",
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {
diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json
index f78191a..8ec44e3 100644
--- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json
+++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json
@@ -442,11 +442,11 @@
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {
-  "name":"org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory",
+  "name":"org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector",
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {
-  "name":"org.apache.dubbo.common.extension.factory.SpiExtensionFactory",
+  "name":"org.apache.dubbo.common.extension.inject.SpiExtensionInjector",
   "methods":[{"name":"<init>","parameterTypes":[] }]
 },
 {