You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/10/29 00:52:39 UTC
[dubbo] branch 3.0 updated: support destroy scope bean and spi
extension instance (#9155)
This is an automated email from the ASF dual-hosted git repository.
liujun 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 5ab9afd support destroy scope bean and spi extension instance (#9155)
5ab9afd is described below
commit 5ab9afdf0c2c2f7b873ef8afe1a0809d9bc5269d
Author: Gong Dewei <ky...@qq.com>
AuthorDate: Fri Oct 29 08:52:20 2021 +0800
support destroy scope bean and spi extension instance (#9155)
---
.../common/beans/factory/ScopeBeanFactory.java | 19 +++++++++++++++++
.../org/apache/dubbo/common/context/Lifecycle.java | 4 +++-
.../dubbo/common/extension/ExtensionDirector.java | 7 +++++++
.../dubbo/common/extension/ExtensionLoader.java | 24 +++++++++++++++++-----
.../org/apache/dubbo/rpc/model/ScopeModel.java | 6 ++++++
.../dubbo/common/beans/ScopeBeanFactoryTest.java | 8 ++++++++
.../beans/model/FooBeanWithApplicationModel.java | 13 +++++++++++-
.../beans/model/FooBeanWithFrameworkModel.java | 13 +++++++++++-
.../common/extension/ExtensionDirectorTest.java | 9 ++++++++
.../extension/director/impl/BaseTestService.java | 15 ++++++++++++--
10 files changed, 108 insertions(+), 10 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
index 8a659de..d55df7f 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java
@@ -21,6 +21,9 @@ import org.apache.dubbo.common.beans.support.InstantiationStrategy;
import org.apache.dubbo.common.extension.ExtensionAccessor;
import org.apache.dubbo.common.extension.ExtensionAccessorAware;
import org.apache.dubbo.common.extension.ExtensionPostProcessor;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ScopeModelAccessor;
@@ -38,6 +41,8 @@ import java.util.stream.Collectors;
*/
public class ScopeBeanFactory {
+ protected static final Logger LOGGER = LoggerFactory.getLogger(ScopeBeanFactory.class);
+
private final ScopeBeanFactory parent;
private ExtensionAccessor extensionAccessor;
private List<ExtensionPostProcessor> extensionPostProcessors;
@@ -227,6 +232,20 @@ public class ScopeBeanFactory {
return null;
}
+ public void destroy() {
+ for (BeanInfo beanInfo : registeredBeanInfos) {
+ if (beanInfo.instance instanceof Disposable) {
+ try {
+ Disposable beanInstance = (Disposable) beanInfo.instance;
+ beanInstance.destroy();
+ } catch (Throwable e) {
+ LOGGER.error("An error occurred when destroy bean [name=" + beanInfo.name + ", bean=" + beanInfo.instance + "]: " + e, e);
+ }
+ }
+ }
+ registeredBeanInfos.clear();
+ }
+
static class BeanInfo {
private String name;
private Object instance;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/context/Lifecycle.java b/dubbo-common/src/main/java/org/apache/dubbo/common/context/Lifecycle.java
index 8f8a273..b3ca3bb 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/context/Lifecycle.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/context/Lifecycle.java
@@ -16,12 +16,14 @@
*/
package org.apache.dubbo.common.context;
+import org.apache.dubbo.common.resource.Disposable;
+
/**
* The Lifecycle of Dubbo component
*
* @since 2.7.5
*/
-public interface Lifecycle {
+public interface Lifecycle extends Disposable {
/**
* Initialize the component before {@link #start() start}
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 d65228a..1cb0e3f 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
@@ -132,4 +132,11 @@ public class ExtensionDirector implements ExtensionAccessor {
public void removeAllCachedLoader() {
// extensionLoadersMap.clear();
}
+
+ public void destroy() {
+ for (ExtensionLoader<?> extensionLoader : extensionLoadersMap.values()) {
+ extensionLoader.destroy();
+ }
+ extensionLoadersMap.clear();
+ }
}
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 d1dcaae..8fa6132 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
@@ -26,6 +26,7 @@ import org.apache.dubbo.common.extension.support.WrapperComparator;
import org.apache.dubbo.common.lang.Prioritized;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.ClassLoaderResourceLoader;
import org.apache.dubbo.common.utils.ClassUtils;
@@ -215,19 +216,32 @@ public class ExtensionLoader<T> {
}
public void destroy() {
+ // destroy raw extension instance
extensionInstances.forEach((type, instance) -> {
- if (instance instanceof Lifecycle) {
- Lifecycle lifecycle = (Lifecycle) instance;
+ if (instance instanceof Disposable) {
+ Disposable disposable = (Disposable) instance;
try {
- lifecycle.destroy();
+ disposable.destroy();
} catch (Exception e) {
- logger.error("Error destroying extension " + lifecycle, e);
+ logger.error("Error destroying extension " + disposable, e);
}
}
});
extensionInstances.clear();
- // TODO destroy extension loader, release resources.
+ // destroy wrapped extension instance
+ for (Holder<Object> holder : cachedInstances.values()) {
+ Object wrappedInstance = holder.get();
+ if (wrappedInstance instanceof Disposable) {
+ Disposable disposable = (Disposable) wrappedInstance;
+ try {
+ disposable.destroy();
+ } catch (Exception e) {
+ logger.error("Error destroying extension " + disposable, e);
+ }
+ }
+ }
+ cachedInstances.clear();
}
private static ClassLoader findClassLoader() {
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 e4bdcfb..9e3559a 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
@@ -107,6 +107,12 @@ public abstract class ScopeModel implements ExtensionAccessor {
for (ClassLoader classLoader : copyOfClassLoaders) {
removeClassLoader(classLoader);
}
+ if (beanFactory != null) {
+ beanFactory.destroy();
+ }
+ if (extensionDirector != null) {
+ extensionDirector.destroy();
+ }
} catch (Throwable t) {
LOGGER.error("Error happened when destroying ScopeModel.", t);
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/ScopeBeanFactoryTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/ScopeBeanFactoryTest.java
index 573b458..3f95fa8 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/ScopeBeanFactoryTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/ScopeBeanFactoryTest.java
@@ -44,5 +44,13 @@ public class ScopeBeanFactoryTest {
Object objectBean = applicationModel.getBeanFactory().getBean(Object.class);
Assertions.assertNull(objectBean);
+
+ Assertions.assertFalse(beanWithApplicationModel.isDestroyed());
+ Assertions.assertFalse(beanWithFrameworkModel.isDestroyed());
+
+ // destroy
+ frameworkModel.destroy();
+ Assertions.assertTrue(beanWithApplicationModel.isDestroyed());
+ Assertions.assertTrue(beanWithFrameworkModel.isDestroyed());
}
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithApplicationModel.java b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithApplicationModel.java
index f103f7a..c580474 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithApplicationModel.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithApplicationModel.java
@@ -16,10 +16,12 @@
*/
package org.apache.dubbo.common.beans.model;
+import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.rpc.model.ApplicationModel;
-public class FooBeanWithApplicationModel {
+public class FooBeanWithApplicationModel implements Disposable {
private ApplicationModel applicationModel;
+ private boolean destroyed;
public FooBeanWithApplicationModel(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
@@ -28,4 +30,13 @@ public class FooBeanWithApplicationModel {
public ApplicationModel getApplicationModel() {
return applicationModel;
}
+
+ @Override
+ public void destroy() {
+ this.destroyed = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithFrameworkModel.java b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithFrameworkModel.java
index d7e357a..e934185 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithFrameworkModel.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/beans/model/FooBeanWithFrameworkModel.java
@@ -16,10 +16,12 @@
*/
package org.apache.dubbo.common.beans.model;
+import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.rpc.model.FrameworkModel;
-public class FooBeanWithFrameworkModel {
+public class FooBeanWithFrameworkModel implements Disposable {
private FrameworkModel frameworkModel;
+ private boolean destroyed;
public FooBeanWithFrameworkModel(FrameworkModel frameworkModel) {
this.frameworkModel = frameworkModel;
@@ -28,4 +30,13 @@ public class FooBeanWithFrameworkModel {
public FrameworkModel getFrameworkModel() {
return frameworkModel;
}
+
+ @Override
+ public void destroy() {
+ this.destroyed = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
}
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 e0031d4..372c3f5 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
@@ -265,5 +265,14 @@ public class ExtensionDirectorTest {
Assertions.assertNull(frameworkService.getAppProvider());
Assertions.assertNull(frameworkService.getModuleProvider());
+ Assertions.assertFalse(moduleService.isDestroyed());
+ Assertions.assertFalse(appService.isDestroyed());
+ Assertions.assertFalse(frameworkService.isDestroyed());
+
+ // destroy
+ frameworkModel.destroy();
+ Assertions.assertTrue(moduleService.isDestroyed());
+ Assertions.assertTrue(appService.isDestroyed());
+ Assertions.assertTrue(frameworkService.isDestroyed());
}
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/BaseTestService.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/BaseTestService.java
index e3171a4..97944e9 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/BaseTestService.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/director/impl/BaseTestService.java
@@ -16,15 +16,17 @@
*/
package org.apache.dubbo.common.extension.director.impl;
+import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ScopeModelAware;
import org.apache.dubbo.rpc.model.ModuleModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
-public class BaseTestService implements ScopeModelAware {
+public class BaseTestService implements ScopeModelAware, Disposable {
private FrameworkModel frameworkModel;
private ApplicationModel applicationModel;
private ModuleModel moduleModel;
+ private volatile boolean destroyed;
@Override
public void setFrameworkModel(FrameworkModel frameworkModel) {
@@ -52,4 +54,13 @@ public class BaseTestService implements ScopeModelAware {
public ModuleModel getModuleModel() {
return moduleModel;
}
+
+ @Override
+ public void destroy() {
+ this.destroyed = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
}