Skip to content
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

Bean definition extending FactoryBean with generics is not injected #27383

Closed
bclozel opened this issue Sep 10, 2021 · 4 comments
Closed

Bean definition extending FactoryBean with generics is not injected #27383

bclozel opened this issue Sep 10, 2021 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: duplicate A duplicate of another issue type: enhancement A general enhancement

Comments

@bclozel
Copy link
Member

bclozel commented Sep 10, 2021

See spring-attic/spring-native#1022 for background.

While working on spring-native, we've found a behavior that might be a bug in the core container support for the functional registration of beans (through instance suppliers).

Some of our samples are failing with org.springframework.beans.factory.NoSuchBeanDefinitionException. The missing bean is of type PluginRegistry<T,S> and is contributed through a PluginRegistryFactoryBean<T,S> (with T and S being concrete types: 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.server.LinkRelationProvider,
org.springframework.hateoas.server.LinkRelationProvider$LookupContext>').

While debugging the issue, we've found that the current code generation process in spring-native contributes that definition to the context with:

BeanDefinitionRegistrar.of("relProviderPluginRegistry", ResolvableType.forClassWithGenerics(PluginRegistryFactoryBean.class, LinkRelationProvider.class, LinkRelationProvider.LookupContext.class)).withFactoryMethod(HateoasConfiguration.class, "relProviderPluginRegistry")
            .instanceSupplier(() -> context.getBean(HateoasConfiguration.class).relProviderPluginRegistry()).register(context);

The important part is that we're declaring the PluginRegistryFactoryBean type as the ResolvableType target type in the definition; this seems to confuse the core container in the org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency and especially the org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates sequence. Instead of considering the generic type of the bean produced by the FactoryBean and if it's assignable to the required type for the injection point, this seems to only consider the provided target type.

This might be linked with the fact that we're heavily using the instanceSupplier mechanism instead of factory methods.

We've validated that providing the type produced by the Factory directly as the target ResolvableType (so 'PluginRegistry<LinkRelationProvider, LookupContext>' instead of 'PluginRegistryFactoryBean<LinkRelationProvider, LookupContext>' solves the issue.

We need to consider this case and know whether this behavior is expected or if this shows a problem with the current suport of instance suppliers.

@bclozel
Copy link
Member Author

bclozel commented Sep 14, 2021

Closing in favor of spring-attic/spring-native#1030

@bclozel bclozel closed this as completed Sep 14, 2021
@bclozel bclozel added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Sep 14, 2021
@snicoll snicoll reopened this Sep 15, 2021
@snicoll snicoll added type: bug A general bug status: waiting-for-triage An issue we've not yet triaged or decided on and removed status: declined A suggestion or change that we don't feel we should currently apply labels Sep 15, 2021
@snicoll
Copy link
Member

snicoll commented Sep 15, 2021

Discussing this topic further, we'd still like to experiment how we can check the FactoryBean type in GenericTypeAwareAutowireCandidateResolver.

@snicoll
Copy link
Member

snicoll commented Sep 15, 2021

The following bean definition fails to inject the plugin registry:

BeanDefinitionRegistrar.of("relProviderPluginRegistry", ResolvableType.forClassWithGenerics(PluginRegistryFactoryBean.class, LinkRelationProvider.class, LinkRelationProvider.LookupContext.class)).withFactoryMethod(HateoasConfiguration.class, "relProviderPluginRegistry")
            .instanceSupplier(() -> context.getBean(HateoasConfiguration.class).relProviderPluginRegistry()).register(context);

If we move the target type to the actual type produced by the BeanFactory, injection is successful:

BeanDefinitionRegistrar.of("relProviderPluginRegistry", ResolvableType.forClassWithGenerics(PluginRegistry.class, LinkRelationProvider.class, LinkRelationProvider.LookupContext.class)).withFactoryMethod(HateoasConfiguration.class, "relProviderPluginRegistry")
            .instanceSupplier(() -> context.getBean(HateoasConfiguration.class).relProviderPluginRegistry()).register(context);

@rstoyanchev rstoyanchev added the in: core Issues in core modules (aop, beans, core, context, expression) label Nov 11, 2021
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on type: bug A general bug labels Dec 29, 2023
@jhoeller jhoeller added this to the 6.x Backlog milestone Dec 29, 2023
@jhoeller jhoeller modified the milestones: 6.x Backlog, 6.2.x Feb 28, 2024
@jhoeller
Copy link
Contributor

jhoeller commented Apr 8, 2024

As far as I can tell, this is effectively a duplicate of #29385 where we determine the nested generic from a FactoryBean target type. And as of the recent revision in #32489 and in particular #32590, I see no such cases left uncovered anymore.

@jhoeller jhoeller closed this as completed Apr 8, 2024
@jhoeller jhoeller added the status: duplicate A duplicate of another issue label Apr 8, 2024
@jhoeller jhoeller removed this from the 6.2.x milestone Apr 8, 2024
@snicoll snicoll closed this as not planned Won't fix, can't repro, duplicate, stale Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: duplicate A duplicate of another issue type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants