如何动态地将外部定义的bean定义添加到Spring上下文?

时间:2014-08-27 17:52:57

标签: java spring spring-mvc

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

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

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

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

任何想法专家?

1 个答案:

答案 0 :(得分:3)

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

这两个类都将BeanDefinitionRegistry作为依赖项,即bucket,在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>

唯一的问题是,您的dataSource无法访问任何属性占位符基础结构,这就是我倾向于使用程序化解决方案的原因。

一般来说,不用担心使用bean来创建bean。他们只需要独立。顺便说一句,强大的Java Config引导也是一个BeanDefinitionRegistryPostProcessor。

有关动态bean定义的更多详细信息,请访问:How to create dynamic bean definitions in Spring

可以在此处找到有关Spring Bean生命周期的非常好的介绍:SpringONE 2013 Presentation by Mark Secrist

希望有所帮助, 这么久。