【问题标题】:How to dynamically add externally defined beans definitions to Spring context?如何将外部定义的 bean 定义动态添加到 Spring 上下文中?
【发布时间】:2014-08-27 17:52:56
【问题描述】:

我有一个要求,需要从“外部”源动态加载 Spring bean 定义。此外部源可以是某种类型的文件、数据库或 Web 服务。

我已经阅读了可以执行此类操作的 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 类,但我遇到了一个巨大的挑战:

从外部源检索 bean 定义信息的对象被配置为 bean 本身(例如 DatabaseBeanDefinitionProvider),因此它需要配置所有依赖项(例如 DataSource)并且可以从上下文中获取数据。

我不确定在 Spring 应用程序上下文生命周期中的何处/何时执行此操作:本质上是使用“现有 bean 来添加新 bean”到上下文中。

有什么想法专家吗?

【问题讨论】:

  • 我认为您需要动态创建和管理子上下文。几乎没有办法将 bean 定义添加到已经初始化的上下文中(或者每次修改 bean 定义时都需要refresh 上下文)。
  • 您要动态添加的 bean 是否都实现了一组已知的接口?
  • @PavelHoral - 这些动态 bean 的加载是一个应用程序初始化过程,因此它只需要刷新一次(我认为),尽管我仍然有点不确定初始化的位置这样做。
  • @JohnR - 不幸的是,它们没有实现通用接口。
  • 正如@PavelHoral 提到的,子上下文听起来是个不错的选择。你有没有尝试/考虑过like this Spring Integration sample?虽然它使用的是 Spring Integration,但基本原理是一样的。

标签: java spring spring-mvc


【解决方案1】:

使用数据库表加载持久化 bean 定义的可能性已经在 Spring 中通过 JdbcBeanDefinitionReader 实现。我提到这一点只是为了确保您不会重新发明轮子;)。如果您只想依赖普通文件中的一堆属性,也可以使用 PropertiesBeanDefinitionReader。

两个类都将 BeanDefinitionRegistry 作为依赖项,即存储桶,在 bean 定义加载阶段将收集所有 bean 定义。实现 BeanDefinitionRegistryPostProcessor (BDRPP) 接口以非常方便的方式提供了这一点。

现在,如何让它运行: 基本上,如果您坚持 DataSource 绑定方式,我建议您手动设置这些依赖项,这意味着在自己的 ApplicationContextInitializer 实现中实例化 BDRPP 和依赖项。然后,您可以在那里调用 applicationContext.addBeanFactoryPostProcessor(yourBdrpp) 并加载 JdbcBeanDefinitionReader 下的 DataSource 所需的任何属性。

如果您的所有依赖项都独立于任何自动装配或属性替换,XML 也可以正常工作。您需要明确定义它们,例如

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

<bean class="net.bensteinert.MyBeanDefinitionRegistryPostProcessor">
    <constructor-arg ref="jdbcTemplate"/>
</bean>

唯一的问题是,您的数据源将无法访问任何属性占位符基础结构,这就是我倾向于编程解决方案的原因。

一般来说,不用担心使用 bean 创建 bean。他们只需要独立。对了,强大的Java Config bootstrapping也是一个BeanDefinitionRegistryPostProcessor。

关于动态 bean 定义的更多细节也可以在这里找到:How to create dynamic bean definitions in Spring

关于 Spring Bean 生命周期的一个很好的介绍可以在这里找到:SpringONE 2013 Presentation by Mark Secrist

希望对您有所帮助, 这么久。

【讨论】:

    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-25
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多