通过BeanFactory.getBean(Class <t>)检索通用bean

时间:2017-12-11 10:48:28

标签: java spring generics

使用Spring 4.x,我可以轻松自动装配一个通用bean,让Spring安全地找到它,即使容器bean是通用的。

E.g。以下工作(见also

class MyBean {

    @Autowired
    private Dao<Entity> dao;

}

class MyBean<T> {

    @Autowired
    private Dao<T> dao;

}

但是我有时需要在方法执行期间在运行时检索bean而不是依赖于自动装配(例如,在上下文初始化期间bean可能还没有准备好)

private myCode() {

    BeanFactory beanFactory; //or ConfigurableListableBeanFactory too

    Dao<Entity> dao = beanFactory.getBean(....????....);
}

考虑:

  • BeanFactory.getBean接受bean名称和/或类型参数。我可以或不可能在运行时知道bean的名字
  • Dao.class解析为Dao的任何通用实现(例如Dao和Dao)

问题是:

如何调用BeanFactory来获取绑定到给定类型的bean实例?

相关:我知道当您需要将调用绑定到返回类型RestTemplate时(当您知道T时),Spring的List<T>需要ParameterizedTypeReference

2 个答案:

答案 0 :(得分:2)

从Spring 4.X.X版本开始,您只需为ApplicationContext自动布线,因为它现在实现了BeanFactory接口。示例:

@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;
    }         

}

答案 1 :(得分:0)

以下解决方法有效。但是我不会接受我的回答,因为解决方法缺乏可读性并且受到未经检查的强制转换

的影响
String[] names = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Dao.class, Entity.class));
Dao<Entity> dao = beanFactory.getBean(names[0], Dao.class);

基本原理:Spring允许为参数化类型获取bean名称。假设第一个调用只返回一个结果,第二个调用返回该bean。不幸的是,第二次调用会生成编译器时间警告