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 2019/12/13 07:24:50 UTC

[dubbo] 09/14: introduce loading strategy to have chance to change loader's behavior

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

liujun pushed a commit to branch master-hsf
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 2d51bf7276cd27d935b31800115e78c604e68e82
Author: Ian Luo <ia...@gmail.com>
AuthorDate: Tue Nov 26 17:32:47 2019 +0800

    introduce loading strategy to have chance to change loader's behavior
---
 .../dubbo/common/extension/ExtensionLoader.java    | 45 ++++++++++++++++------
 .../dubbo/common/extension/LoadingStrategy.java    | 13 +++++++
 2 files changed, 46 insertions(+), 12 deletions(-)

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 2f77ee3..cb88515 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
@@ -99,6 +99,16 @@ public class ExtensionLoader<T> {
 
     private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<>();
 
+    private static LoadingStrategy DUBBO_INTERNAL_STRATEGY =  () -> DUBBO_INTERNAL_DIRECTORY;
+    private static LoadingStrategy DUBBO_STRATEGY = () -> DUBBO_DIRECTORY;
+    private static LoadingStrategy SERVICES_STRATEGY = () -> SERVICES_DIRECTORY;
+
+    private static LoadingStrategy[] strategies = new LoadingStrategy[] { DUBBO_INTERNAL_STRATEGY, DUBBO_STRATEGY, SERVICES_STRATEGY };
+
+    public static void setLoadingStrategies(LoadingStrategy... strategies) {
+        ExtensionLoader.strategies = strategies;
+    }
+
     private ExtensionLoader(Class<?> type) {
         this.type = type;
         objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
@@ -628,14 +638,12 @@ public class ExtensionLoader<T> {
         cacheDefaultExtensionName();
 
         Map<String, Class<?>> extensionClasses = new HashMap<>();
-        // internal extension load from ExtensionLoader's ClassLoader first
-        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName(), true);
-        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"), true);
-
-        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
-        loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
-        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
-        loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
+
+        for (LoadingStrategy strategy : strategies) {
+            loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.excludedPackages());
+            loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.excludedPackages());
+        }
+
         return extensionClasses;
     }
 
@@ -663,7 +671,8 @@ public class ExtensionLoader<T> {
         loadDirectory(extensionClasses, dir, type, false);
     }
 
-    private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type, boolean extensionLoaderClassLoaderFirst) {
+    private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
+                               boolean extensionLoaderClassLoaderFirst, String... excludedPackages) {
         String fileName = dir + type;
         try {
             Enumeration<java.net.URL> urls = null;
@@ -688,7 +697,7 @@ public class ExtensionLoader<T> {
             if (urls != null) {
                 while (urls.hasMoreElements()) {
                     java.net.URL resourceURL = urls.nextElement();
-                    loadResource(extensionClasses, classLoader, resourceURL);
+                    loadResource(extensionClasses, classLoader, resourceURL, excludedPackages);
                 }
             }
         } catch (Throwable t) {
@@ -697,7 +706,8 @@ public class ExtensionLoader<T> {
         }
     }
 
-    private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL) {
+    private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
+                              java.net.URL resourceURL, String... excludedPackages) {
         try {
             try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
                 String line;
@@ -715,7 +725,7 @@ public class ExtensionLoader<T> {
                                 name = line.substring(0, i).trim();
                                 line = line.substring(i + 1).trim();
                             }
-                            if (line.length() > 0) {
+                            if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
                                 loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name);
                             }
                         } catch (Throwable t) {
@@ -731,6 +741,17 @@ public class ExtensionLoader<T> {
         }
     }
 
+    private boolean isExcluded(String className, String... excludedPackages) {
+        if (excludedPackages != null) {
+            for (String excludePackage : excludedPackages) {
+                if (className.startsWith(excludePackage + ".")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
         if (!type.isAssignableFrom(clazz)) {
             throw new IllegalStateException("Error occurred when loading extension class (interface: " +
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java
new file mode 100644
index 0000000..6c98795
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/LoadingStrategy.java
@@ -0,0 +1,13 @@
+package org.apache.dubbo.common.extension;
+
+public interface LoadingStrategy {
+    String directory();
+
+    default boolean preferExtensionClassLoader() {
+        return false;
+    }
+
+    default String[] excludedPackages() {
+        return null;
+    }
+}