diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java index b18244bec3..a1267f01a6 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java @@ -4,6 +4,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.annotation.JacksonInject; @@ -70,6 +71,12 @@ public abstract class DeserializationContext */ protected final DeserializerCache _cache; + /** + * Object that caches the injectable values already resolved, + * to avoid executing the injection logic multiple times + */ + protected final Map _injectablesCache; + /* /********************************************************** /* Configuration, changeable via fluent factories @@ -169,6 +176,7 @@ protected DeserializationContext(DeserializerFactory df, cache = new DeserializerCache(); } _cache = cache; + _injectablesCache = new ConcurrentHashMap<>(); _featureFlags = 0; _readCapabilities = null; _config = null; @@ -181,6 +189,7 @@ protected DeserializationContext(DeserializationContext src, DeserializerFactory factory) { _cache = src._cache; + _injectablesCache = src._injectablesCache; _factory = factory; _config = src._config; @@ -199,6 +208,7 @@ protected DeserializationContext(DeserializationContext src, DeserializerCache cache) { _cache = cache; + _injectablesCache = src._injectablesCache; _factory = src._factory; _config = src._config; @@ -218,6 +228,7 @@ protected DeserializationContext(DeserializationContext src, InjectableValues injectableValues) { _cache = src._cache; + _injectablesCache = src._injectablesCache; _factory = src._factory; // 08-Jun-2020. tatu: Called only for `ObjectMapper.canDeserialize()` // (see [databind#2749]), not sure what's the best work-around but @@ -242,6 +253,7 @@ protected DeserializationContext(DeserializationContext src, DeserializationConfig config) { _cache = src._cache; + _injectablesCache = src._injectablesCache; _factory = src._factory; _readCapabilities = null; @@ -259,6 +271,7 @@ protected DeserializationContext(DeserializationContext src, */ protected DeserializationContext(DeserializationContext src) { _cache = src._cache.emptyCopy(); + _injectablesCache = src._injectablesCache; _factory = src._factory; _config = src._config; @@ -479,7 +492,19 @@ public final Object findInjectableValue(Object valueId, "No 'injectableValues' configured, cannot inject value with id '%s'", valueId), valueId, forProperty, beanInstance); } - return _injectableValues.findInjectableValue(this, valueId, forProperty, beanInstance, optional); + + Object value = _injectablesCache.get(valueId); + + if (value == null) { + value = _injectableValues.findInjectableValue(this, valueId, forProperty, beanInstance, + optional); + + if (value != null) { + _injectablesCache.put(valueId, value); + } + } + + return value; } /** diff --git a/src/test/java/com/fasterxml/jackson/databind/tofix/JacksonInject4218Test.java b/src/test/java/com/fasterxml/jackson/databind/deser/inject/JacksonInject4218Test.java similarity index 91% rename from src/test/java/com/fasterxml/jackson/databind/tofix/JacksonInject4218Test.java rename to src/test/java/com/fasterxml/jackson/databind/deser/inject/JacksonInject4218Test.java index 473f089598..c406337a9d 100644 --- a/src/test/java/com/fasterxml/jackson/databind/tofix/JacksonInject4218Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/inject/JacksonInject4218Test.java @@ -1,4 +1,4 @@ -package com.fasterxml.jackson.databind.tofix; +package com.fasterxml.jackson.databind.deser.inject; import org.junit.jupiter.api.Test; @@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; -import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -51,7 +50,6 @@ public Object findInjectableValue( } // [databind#4218] - @JacksonTestFailureExpected @Test void injectFail4218() throws Exception {