[Gen AI] Fix 11758: Ensure @Replaces beans are detected globally #12144
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue: #11758
Bug description
The bug occurs because replacement beans (
@Replaces) are only discovered among the candidate collection being considered, not across the global registry. As a result, replacements declared elsewhere in the registry (e.g., a non-@Contextreplacement for a@Context bean) can be missed, and already-cached singleton instances for the replaced bean can remain in singleton caches, leading to nondeterministic behavior.Solution / fix
The test defines an @Context-scoped bean (
OriginalContextApi) and a@Singletonreplacement (ReplacementSingletonApi) annotated with@Replaces(OriginalContextApi). It asserts that after starting the ApplicationContext, the original@Contextbean is not instantiated and that injecting ReplacedApi yields the replacement. On the original code, the test fails because the original@Contextbean is eagerly created, reproducing the reported issue where replacing a@Contextbean with a non-@context bean still instantiates the original. This is aligned with the issue description. 2)Patch effectiveness: The patch makes two key changes. In
DefaultBeanContext, it scans all bean definitions for replacements and prunes any eager (@Context) beans fromeagerInitif they are replaced, regardless of the replacement's scope. This ensures the original @context bean is not eagerly created when there is any replacement, even if the replacement is not@Context. InSingletonScope, it removes the fallback fromfindBeanRegistrationByExactDefinitionto the type/qualifier-based cache, preventing returning a previously created instance of a different bean definition. This addresses the nondeterministic case where an original singleton could be returned because it matched by type/qualifier. Together, these changes fix both parts of the issue: preventing unwanted eager instantiation and ensuring correct bean selection by exact definition.Steps to reproduce