diff --git a/core/src/main/java/io/github/xanthic/cache/core/CacheApiSettings.java b/core/src/main/java/io/github/xanthic/cache/core/CacheApiSettings.java index 94f12db0..1dd9844b 100644 --- a/core/src/main/java/io/github/xanthic/cache/core/CacheApiSettings.java +++ b/core/src/main/java/io/github/xanthic/cache/core/CacheApiSettings.java @@ -23,8 +23,6 @@ */ @Slf4j public final class CacheApiSettings { - private static volatile CacheApiSettings INSTANCE; - private final Map, CacheProvider> providers = Collections.synchronizedMap(new IdentityHashMap<>(16)); private final AtomicReference> defaultCacheProvider = new AtomicReference<>(); @@ -38,7 +36,7 @@ public final class CacheApiSettings { private volatile MisconfigurationPolicy defaultMisconfigurationPolicy = MisconfigurationPolicy.IGNORE; private CacheApiSettings() { - // restrict instantiation + this.populateProviders(); } /** @@ -102,31 +100,14 @@ public void registerCacheProvider(@NonNull Class cacheP } } - /** - * @return the cache api settings singleton - */ - @NotNull - public static CacheApiSettings getInstance() { - if (INSTANCE == null) { - synchronized (CacheApiSettings.class) { - if (INSTANCE == null) { - CacheApiSettings cacheApiSettings = new CacheApiSettings(); - populateProviders(cacheApiSettings); - INSTANCE = cacheApiSettings; - } - } - } - return INSTANCE; - } - - private static void populateProviders(CacheApiSettings cacheApiSettings) { + private void populateProviders() { log.debug("Xanthic: Registering canonical cache providers from the classpath..."); AtomicInteger registered = new AtomicInteger(); Consumer loadImpl = (providerClass) -> { try { Class clazz = Class.forName(providerClass).asSubclass(CacheProvider.class); - cacheApiSettings.registerCacheProvider(clazz, null); // lazy, init if needed + registerCacheProvider(clazz, null); // lazy, init if needed registered.incrementAndGet(); } catch (ClassNotFoundException cx) { log.trace("Xanthic: Could not find optional cache provider " + providerClass); @@ -148,4 +129,16 @@ private static void populateProviders(CacheApiSettings cacheApiSettings) { log.debug("Xanthic: Loaded {} canonical cache provider(s) on settings construction!", registered.get()); } + + /** + * @return the cache api settings singleton + */ + @NotNull + public static CacheApiSettings getInstance() { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder { + private static final CacheApiSettings INSTANCE = new CacheApiSettings(); + } } diff --git a/core/src/test/java/io/github/xanthic/cache/core/CacheRegistrationTest.java b/core/src/test/java/io/github/xanthic/cache/core/CacheRegistrationTest.java index 4b770dc2..e1610946 100644 --- a/core/src/test/java/io/github/xanthic/cache/core/CacheRegistrationTest.java +++ b/core/src/test/java/io/github/xanthic/cache/core/CacheRegistrationTest.java @@ -12,7 +12,10 @@ import org.junit.jupiter.api.Test; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.time.Duration; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -23,10 +26,19 @@ public class CacheRegistrationTest { @SneakyThrows void beforeEachTest() { // reset cache settings singleton - Field instanceField = CacheApiSettings.class.getDeclaredField("INSTANCE"); - instanceField.setAccessible(true); - instanceField.set(null, null); - CacheApiSettings.getInstance(); + CacheApiSettings instance = CacheApiSettings.getInstance(); + + Field providers = CacheApiSettings.class.getDeclaredField("providers"); + providers.setAccessible(true); + ((Map) providers.get(instance)).clear(); + + Field defaultProvider = CacheApiSettings.class.getDeclaredField("defaultCacheProvider"); + defaultProvider.setAccessible(true); + ((AtomicReference) defaultProvider.get(instance)).set(null); + + Method populate = CacheApiSettings.class.getDeclaredMethod("populateProviders"); + populate.setAccessible(true); + populate.invoke(instance); } @Test