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

usr*_*ΛΩΝ 4 java generics spring

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

例如以下工作(见)

class MyBean {

    @Autowired
    private Dao<Entity> dao;

}

class MyBean<T> {

    @Autowired
    private Dao<T> dao;

}
Run Code Online (Sandbox Code Playgroud)

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

private myCode() {

    BeanFactory beanFactory; //or ConfigurableListableBeanFactory too

    Dao<Entity> dao = beanFactory.getBean(....????....);
}
Run Code Online (Sandbox Code Playgroud)

注意事项:

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

问题是:

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

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

usr*_*ΛΩΝ 5

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

String[] names = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Dao.class, Entity.class));
Dao<Entity> dao = beanFactory.getBean(names[0], Dao.class);
Run Code Online (Sandbox Code Playgroud)

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