From c2d9998350b3a15ff7678c9053bca434463cf915 Mon Sep 17 00:00:00 2001 From: Ajith Kumar Date: Tue, 20 Oct 2020 14:36:15 +0530 Subject: Bucketed caching in SingletonExtensionFactory (#402) --- .../java/org/pf4j/SingletonExtensionFactory.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'pf4j/src/main/java') diff --git a/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java b/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java index 725b9a7..ff94652 100644 --- a/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java +++ b/pf4j/src/main/java/org/pf4j/SingletonExtensionFactory.java @@ -19,36 +19,46 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.WeakHashMap; /** * An {@link ExtensionFactory} that always returns a specific instance. * Optional, you can specify the extension classes for which you want singletons. * * @author Decebal Suiu + * @author Ajith Kumar */ public class SingletonExtensionFactory extends DefaultExtensionFactory { private final List extensionClassNames; - private Map cache; + private Map> cache; public SingletonExtensionFactory(String... extensionClassNames) { this.extensionClassNames = Arrays.asList(extensionClassNames); - cache = new HashMap<>(); // simple cache implementation + cache = new WeakHashMap<>(); // simple cache implementation } @Override @SuppressWarnings("unchecked") public T create(Class extensionClass) { String extensionClassName = extensionClass.getName(); - if (cache.containsKey(extensionClassName)) { - return (T) cache.get(extensionClassName); + ClassLoader extensionClassLoader = extensionClass.getClassLoader(); + + if (!cache.containsKey(extensionClassLoader)) { + cache.put(extensionClassLoader, new HashMap<>()); + } + + Map classLoaderBucket = cache.get(extensionClassLoader); + + if (classLoaderBucket.containsKey(extensionClassName)) { + return (T) classLoaderBucket.get(extensionClassName); } T extension = super.create(extensionClass); if (extensionClassNames.isEmpty() || extensionClassNames.contains(extensionClassName)) { - cache.put(extensionClassName, extension); + classLoaderBucket.put(extensionClassName, extension); } return extension; -- cgit v1.2.3