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 <[email protected]> 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; + } +}
