-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat(#4218): avoid executing the injection logic multiple times #5201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(#4218): avoid executing the injection logic multiple times #5201
Conversation
…Context to avoid executing the injection logic multiple times
|
||
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this make injectino logic to run exactly once? Or less than before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly once, as proven by this test, which doesn't fail anymore with the change above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that is true: while locating the value only occurs just once, wouldn't actual injection occur multiple times still? While this results in same value being used, it still calls injection (pass via constructor, set field) more than once. Ideally I'd rather neither would happen more than once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. The value is either found in cache or actually resolved, but the injection happens anyway.
@@ -169,6 +176,7 @@ protected DeserializationContext(DeserializerFactory df, | |||
cache = new DeserializerCache(); | |||
} | |||
_cache = cache; | |||
_injectablesCache = new ConcurrentHashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need not be thread-safe, single deserialization calls are never concurrent. So simple HashMap
would do.
Single DeserializationContext
is only ever used for single readValue()
call.
Also: should not eagerly construct Map
since this imposes cost for all usage, even when (like in most cases I'd guess) no injection is required.
So should instead lazily construct when needed.
All of this assuming we actually want caching. Not sold on that yet either.
I don't really like this approach: to me it is working around the issue, instead of solving it. I'd rather that actual injection duplication is avoided, not just lookup. |
closing since it's a workaround not addressing the root cause of the issue |
Thank you still @giulong ! |
Opened #5224 with a better implementation |
Given there are multiple entry points for injection (creator properties vs fields and setters), would a cache in
DeserializationContext
be good to avoid executing the injection logic multiple times? Is the tradeoff of having a bit more space consumption vs much lower (I guess) execution time performance worth it?Especially considering that every new feature added in the
@JacksonInject
context, without a cache would mean duplicating the logic in a slightly different way, since creator properties and fields injection are managed differently.