我有一个要求,即需要从“外部”源动态加载Spring bean定义。此外部源可以是某种类型的文件,数据库或Web服务。
我已经阅读了可以执行此类操作的BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
类,但我遇到了一个巨大的挑战:
从外部源检索bean定义信息的对象被配置为bean本身(例如DatabaseBeanDefinitionProvider),因此需要配置所有依赖项(例如DataSource)并从上下文中获取以获取数据。 / p>
我不确定Spring应用程序上下文生命周期中的何时/何时执行此操作:基本上使用“现有bean将新bean添加到上下文中”。
任何想法专家?
答案 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
希望有所帮助, 这么久。