Skip to content

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

Conversation

giulong
Copy link
Contributor

@giulong giulong commented Jun 20, 2025

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.

Comment on lines +495 to +507

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;
Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Contributor Author

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<>();
Copy link
Member

@cowtowncoder cowtowncoder Jul 10, 2025

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.

@cowtowncoder
Copy link
Member

I don't really like this approach: to me it is working around the issue, instead of solving it.
I think performance effect may be modest or non-existing for common case of injectable values being passed in a Map -- if so, we'd create one more Map to hold contents of another Map, essentially?

I'd rather that actual injection duplication is avoided, not just lookup.

@giulong
Copy link
Contributor Author

giulong commented Jul 13, 2025

closing since it's a workaround not addressing the root cause of the issue

@giulong giulong closed this Jul 13, 2025
@JooHyukKim
Copy link
Member

Thank you still @giulong !

@giulong
Copy link
Contributor Author

giulong commented Jul 14, 2025

Opened #5224 with a better implementation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants