Skip to content

getBeanNamesForType(ResolvableType) doesn't match generic factory method return type for yet-to-be-created bean [SPR-15011] #19578

Closed
@spring-projects-issues

Description

@spring-projects-issues

Phil Webb opened SPR-15011 and commented

Originally raised as a @SpyBean issue with Spring Boot. When calling beanFactory.getBeanNamesForType from a BeanFactoryPostProcessor the predictBeanType method does not consider generics. This means given a bean definition Foo<String> calling ResolvableType.forClassWithGenerics(Foo.class, String.class) will not work.

Here's a minimal test case:

import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.Order;

public class GenericBeanTests {

	@Test
	public void test() {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(Config.class);
		context.register(TestPostProcessor.class);
		context.refresh();
		context.close();
	}

	@Order(Ordered.LOWEST_PRECEDENCE)
	public static class TestPostProcessor implements BeanFactoryPostProcessor {

		@Override
		public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
			assertTrue(beanFactory.getBeanNamesForType(Foo.class).length > 0);
			assertTrue(beanFactory.getBeanNamesForType(ResolvableType.forClass(Foo.class)).length > 0);
			assertTrue(beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Foo.class, String.class)).length > 0);
		}

	}

	@Configuration
	public static class Config {

		@Bean
		public Foo<String> fooBean() {
			return new StringFoo();
		}

	}

	public static interface Foo<T> {

	}

	public static class StringFoo implements Foo<String> {

	}

}

Affects: 4.3.4

Issue Links:

1 votes, 3 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions