Skip to content

Commit

Permalink
Merge pull request #8 from chickenlj/loading-strategy
Browse files Browse the repository at this point in the history
introduce loading strategy to have chance to change loader's behavior
  • Loading branch information
chickenlj authored Nov 27, 2019
2 parents 3b8f3d4 + 2d51bf7 commit a7faeb4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -628,14 +638,12 @@ private Map<String, Class<?>> loadExtensionClasses() {
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;
}

Expand Down Expand Up @@ -663,7 +671,8 @@ private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, S
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;
Expand All @@ -688,7 +697,7 @@ private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, S
if (urls != null) {
while (urls.hasMoreElements()) {
java.net.URL resourceURL = urls.nextElement();
loadResource(extensionClasses, classLoader, resourceURL);
loadResource(extensionClasses, classLoader, resourceURL, excludedPackages);
}
}
} catch (Throwable t) {
Expand All @@ -697,7 +706,8 @@ private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, S
}
}

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;
Expand All @@ -715,7 +725,7 @@ private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader cl
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) {
Expand All @@ -731,6 +741,17 @@ private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader cl
}
}

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: " +
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit a7faeb4

Please sign in to comment.