Reputation: 26874
With Spring 4.x I can easily autowire a generic bean and have Spring find it safely, even if the container bean is generic.
E.g. the following work (see also)
class MyBean {
@Autowired
private Dao<Entity> dao;
}
class MyBean<T> {
@Autowired
private Dao<T> dao;
}
However I sometimes need to retrieve beans at runtime during method execution instead of relying on autowiring (e.g. the beans may not be ready yet during context initialization)
private myCode() {
BeanFactory beanFactory; //or ConfigurableListableBeanFactory too
Dao<Entity> dao = beanFactory.getBean(....????....);
}
Considerations:
Questions is:
Related: I know that Spring's RestTemplate
requires a ParameterizedTypeReference when you need to bind a call to a return type of List<T>
(when you know T)
Upvotes: 4
Views: 5583
Reputation: 791
Since Spring version 4.X.X you simply autowire the ApplicationContext
as it now implements the BeanFactory
interface. Example:
@Component
public class BeanUtil {
@Autowired
private ApplicationContext applicationContext;
public Parent get() {
ResolvableType resolvableType = ResolvableType.forClassWithGenerics(Parent.class, ResolvableType.forClass(Child.class));
String[] beanNames = applicationContext.getBeanNamesForType(resolvableType);
assert beanNames.length == 1;
String beanName = beanNames[0];
Parent parent = applicationContext.getBean(beanName, Parent.class);
return parent;
}
}
Upvotes: 3
Reputation: 26874
The following workaround works. However I will NOT accept my answer because the workaround lacks readability and is affected by an unchecked cast
String[] names = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Dao.class, Entity.class));
Dao<Entity> dao = beanFactory.getBean(names[0], Dao.class);
Rationale: Spring allows to get bean names for a parameterized type. Under the assumption that the first call returns only one result, the second works by returning that bean. Unfortunately, the second call generates a compiler time warning
Upvotes: 5