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/09/08 07:47:02 UTC

[dubbo] branch 3.0 updated: [3.0] Opt Scope Model (#8717)

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 5bf321c  [3.0] Opt Scope Model (#8717)
5bf321c is described below

commit 5bf321c78a8a9fad11442933d9bf0f24fe835d9a
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Wed Sep 8 15:46:47 2021 +0800

    [3.0] Opt Scope Model (#8717)
    
    * Add ScopeModel Destroy Listener Support
    
    * Add ApplicationModel to DubboBootstrap binding refer
    
    * Fix ut
---
 .../apache/dubbo/rpc/model/ApplicationModel.java    |  2 +-
 .../org/apache/dubbo/rpc/model/FrameworkModel.java  |  1 +
 .../org/apache/dubbo/rpc/model/ModuleModel.java     |  3 ++-
 .../java/org/apache/dubbo/rpc/model/ScopeModel.java | 20 ++++++++++++++++++++
 .../dubbo/rpc/model/ScopeModelDestroyListener.java  | 21 +++++++++++++++++++++
 .../org/apache/dubbo/config/ReferenceConfig.java    |  9 ++++++---
 .../java/org/apache/dubbo/config/ServiceConfig.java |  2 +-
 .../dubbo/config/bootstrap/DubboBootstrap.java      | 18 ++++++++++++++++++
 .../apache/dubbo/config/ReferenceConfigTest.java    |  2 +-
 9 files changed, 71 insertions(+), 7 deletions(-)

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 f51b452..dfcde21 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
@@ -205,7 +205,7 @@ public class ApplicationModel extends ScopeModel {
             serviceRepository.destroy();
             serviceRepository = null;
         }
-
+        super.destroy();
     }
 
     public FrameworkModel getFrameworkModel() {
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 d072b6c..a5ff09d 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
@@ -67,6 +67,7 @@ public class FrameworkModel extends ScopeModel {
                 defaultInstance = null;
             }
         }
+        super.destroy();
     }
 
     public static FrameworkModel defaultModel() {
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 b940bc0..aee8b5c 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
@@ -39,6 +39,7 @@ public class ModuleModel extends ScopeModel {
         initialize();
     }
 
+    @Override
     protected void initialize() {
         super.initialize();
         this.serviceRepository = new ModuleServiceRepository(this);
@@ -79,9 +80,9 @@ public class ModuleModel extends ScopeModel {
             serviceRepository = null;
         }
 
-        super.destroy();
         // TODO destroy module resources
         applicationModel.removeModule(this);
+        super.destroy();
     }
 
     public ApplicationModel getApplicationModel() {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
index 35df9c0..6cef351 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
@@ -21,7 +21,11 @@ import org.apache.dubbo.common.extension.ExtensionAccessor;
 import org.apache.dubbo.common.extension.ExtensionDirector;
 import org.apache.dubbo.common.extension.ExtensionScope;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 public abstract class ScopeModel implements ExtensionAccessor {
 
@@ -31,6 +35,9 @@ public abstract class ScopeModel implements ExtensionAccessor {
     private ExtensionDirector extensionDirector;
 
     private ScopeBeanFactory beanFactory;
+    private List<ScopeModelDestroyListener> destroyListeners;
+
+    private Map<String, Object> attribute;
 
     public ScopeModel(ScopeModel parent, ExtensionScope scope) {
         this.parent = parent;
@@ -50,9 +57,22 @@ public abstract class ScopeModel implements ExtensionAccessor {
         this.extensionDirector = new ExtensionDirector(parent != null ? parent.getExtensionDirector() : null, scope);
         this.extensionDirector.addExtensionPostProcessor(new ScopeModelAwareExtensionProcessor(this));
         this.beanFactory = new ScopeBeanFactory(parent != null ? parent.getBeanFactory() : null, extensionDirector);
+        this.destroyListeners = new LinkedList<>();
+        this.attribute = new ConcurrentHashMap<>();
     }
 
     public void destroy() {
+        for (ScopeModelDestroyListener destroyListener : destroyListeners) {
+            destroyListener.onDestroy(this);
+        }
+    }
+
+    public final void addDestroyListener(ScopeModelDestroyListener listener) {
+        destroyListeners.add(listener);
+    }
+
+    public Map<String, Object> getAttribute() {
+        return attribute;
     }
 
     public ExtensionDirector getExtensionDirector() {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModelDestroyListener.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModelDestroyListener.java
new file mode 100644
index 0000000..93f6e84
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModelDestroyListener.java
@@ -0,0 +1,21 @@
+/*
+ * 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.rpc.model;
+
+public interface ScopeModelDestroyListener {
+    void onDestroy(ScopeModel scopeModel);
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index d7c7ab1..c915cee 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -222,8 +222,10 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
         }
         invoker = null;
         ref = null;
-        ModuleServiceRepository repository = getScopeModel().getServiceRepository();
-        repository.unregisterConsumer(consumerModel);
+        if (consumerModel != null) {
+            ModuleServiceRepository repository = getScopeModel().getServiceRepository();
+            repository.unregisterConsumer(consumerModel);
+        }
     }
 
     protected synchronized void init() {
@@ -235,7 +237,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
         // Loading by Spring context will associate bootstrap in afterPropertiesSet() method.
         // Initializing bootstrap here only for compatible with old API usages.
         if (bootstrap == null) {
-            bootstrap = DubboBootstrap.getInstance();
+            bootstrap = DubboBootstrap.getInstance(getScopeModel().getApplicationModel());
             bootstrap.initialize();
             bootstrap.reference(this);
         }
@@ -617,6 +619,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
 
     /**
      * just for test
+     *
      * @return
      */
     @Deprecated
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index e7aae36..fdf6c91 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -200,7 +200,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
     public void init() {
         if (this.initialized.compareAndSet(false, true)) {
             if (this.bootstrap == null) {
-                this.bootstrap = DubboBootstrap.getInstance();
+                this.bootstrap = DubboBootstrap.getInstance(getScopeModel().getApplicationModel());
                 this.bootstrap.initialize();
             }
             this.bootstrap.service(this);
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index 080a9ba..87331c0 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@ -207,6 +207,23 @@ public final class DubboBootstrap {
         return instance;
     }
 
+    public static DubboBootstrap getInstance(ApplicationModel applicationModel) {
+        Map<String, Object> attribute = applicationModel.getAttribute();
+        Object cached = attribute.get(NAME);
+        if (cached instanceof DubboBootstrap) {
+            return (DubboBootstrap) cached;
+        } else {
+            synchronized (applicationModel) {
+                cached = attribute.get(NAME);
+                if (cached instanceof DubboBootstrap) {
+                    return (DubboBootstrap) cached;
+                } else {
+                    return new DubboBootstrap(applicationModel);
+                }
+            }
+        }
+    }
+
     public static DubboBootstrap newInstance() {
         return new DubboBootstrap(new FrameworkModel());
     }
@@ -257,6 +274,7 @@ public final class DubboBootstrap {
 
     private DubboBootstrap(ApplicationModel applicationModel) {
         this.applicationModel = applicationModel;
+        applicationModel.getAttribute().put(NAME, this);
         configManager = applicationModel.getApplicationConfigManager();
         environment = applicationModel.getApplicationEnvironment();
 
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index b6ec83e..a3cd670 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -801,7 +801,7 @@ public class ReferenceConfigTest {
     public void testDifferentClassLoader() throws Exception {
         ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
         ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
-        applicationConfig.getConfigManager().setApplication(applicationConfig);
+        applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
         ModuleModel moduleModel = new ModuleModel(applicationModel);
 
         DemoService demoService = new DemoServiceImpl();