From 2fbcff89199267313dcb7fe1c7fb803f38f22879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Mon, 18 Sep 2023 09:23:34 +0200 Subject: [PATCH] Prevent ValueLoaderEntryProcessor to be created for each get call Closes gh-31250 --- .../cache/jcache/JCacheCache.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java index 2c49c9e73d..c870d843d7 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java @@ -17,6 +17,7 @@ package org.springframework.cache.jcache; import java.util.concurrent.Callable; +import java.util.function.Function; import javax.cache.Cache; import javax.cache.processor.EntryProcessor; @@ -42,6 +43,8 @@ public class JCacheCache extends AbstractValueAdaptingCache { private final Cache cache; + private final ValueLoaderEntryProcessor valueLoaderEntryProcessor; + /** * Create a {@code JCacheCache} instance. @@ -60,6 +63,8 @@ public class JCacheCache extends AbstractValueAdaptingCache { super(allowNullValues); Assert.notNull(jcache, "Cache must not be null"); this.cache = jcache; + this.valueLoaderEntryProcessor = new ValueLoaderEntryProcessor( + this::fromStoreValue, this::toStoreValue); } @@ -81,9 +86,10 @@ public class JCacheCache extends AbstractValueAdaptingCache { @Override @Nullable + @SuppressWarnings("unchecked") public T get(Object key, Callable valueLoader) { try { - return this.cache.invoke(key, new ValueLoaderEntryProcessor(), valueLoader); + return (T) this.cache.invoke(key, this.valueLoaderEntryProcessor, valueLoader); } catch (EntryProcessorException ex) { throw new ValueRetrievalException(key, valueLoader, ex.getCause()); @@ -141,18 +147,29 @@ public class JCacheCache extends AbstractValueAdaptingCache { } - private class ValueLoaderEntryProcessor implements EntryProcessor { + private static final class ValueLoaderEntryProcessor implements EntryProcessor { + + private final Function fromStoreValue; + + private final Function toStoreValue; + + private ValueLoaderEntryProcessor(Function fromStoreValue, + Function toStoreValue) { + + this.fromStoreValue = fromStoreValue; + this.toStoreValue = toStoreValue; + } - @SuppressWarnings("unchecked") @Override @Nullable - public T process(MutableEntry entry, Object... arguments) throws EntryProcessorException { - Callable valueLoader = (Callable) arguments[0]; + @SuppressWarnings("unchecked") + public Object process(MutableEntry entry, Object... arguments) throws EntryProcessorException { + Callable valueLoader = (Callable) arguments[0]; if (entry.exists()) { - return (T) fromStoreValue(entry.getValue()); + return this.fromStoreValue.apply(entry.getValue()); } else { - T value; + Object value; try { value = valueLoader.call(); } @@ -160,7 +177,7 @@ public class JCacheCache extends AbstractValueAdaptingCache { throw new EntryProcessorException("Value loader '" + valueLoader + "' failed " + "to compute value for key '" + entry.getKey() + "'", ex); } - entry.setValue(toStoreValue(value)); + entry.setValue(this.toStoreValue.apply(value)); return value; } }