gpt4 book ai didi

java - 我可以在运行时替换 Spring bean 定义吗?

转载 作者:IT老高 更新时间:2023-10-28 13:01:38 28 4
gpt4 key购买 nike

考虑以下场景。我有一个带有 bean 的 Spring 应用程序上下文,其属性应该是可配置的,例如 DataSourceMailSender。可变的应用程序配置由一个单独的 bean 管理,我们称之为 configuration

管理员现在可以更改配置值,例如电子邮件地址或数据库 URL,我想在运行时重新初始化配置的 bean。

假设我不能简单地修改上面可配置 bean 的属性(例如由 FactoryBean 或构造函数注入(inject)创建),而必须重新创建 bean 本身。

关于如何实现这一目标的任何想法?我也很高兴收到有关如何组织整个配置的建议。没有什么是固定的。 :-)

编辑

澄清一下:我不是在问如何更新配置或如何注入(inject)静态配置值。我会尝试一个例子:

<beans>
<util:map id="configuration">
<!-- initial configuration -->
</util:map>

<bean id="constructorInjectedBean" class="Foo">
<constructor-arg value="#{configuration['foobar']}" />
</bean>

<bean id="configurationService" class="ConfigurationService">
<property name="configuration" ref="configuration" />
</bean>
</beans>

所以有一个使用构造函数注入(inject)的bean constructorInjectedBean。想象一下 bean 的构造非常昂贵,所以使用原型(prototype)作用域或工厂代理不是一种选择,想想 DataSource

我想要做的是每次更新配置时(通过 configurationService bean constructorInjectedBean 正在重新创建并重新注入(inject)到应用程序上下文中并依赖 bean 。

我们可以放心地假设 constructorInjectedBean 正在使用接口(interface),因此代理魔法确实是一种选择。

我希望这个问题更清楚一点。

最佳答案

这是我过去的做法:运行依赖于可以动态更改的配置的服务实现生命周期接口(interface):IRefreshable:

public interface IRefreshable {
// Refresh the service having it apply its new values.
public void refresh(String filter);

// The service must decide if it wants a cache refresh based on the refresh message filter.
public boolean requiresRefresh(String filter);
}

Controller (或服务)可以将配置广播修改为配置已更改的 JMS 主题(提供配置对象的名称)。然后,消息驱动 bean 调用所有实现 IRefreshable 的 bean 上的 IRefreshable 接口(interface)协定。

spring 的好处是您可以自动检测应用程序上下文中需要刷新的任何服务,而无需显式配置它们:

public class MyCacheSynchService implements InitializingBean, ApplicationContextAware {
public void afterPropertiesSet() throws Exception {
Map<String, ?> refreshableServices = m_appCtx.getBeansOfType(IRefreshable.class);
for (Map.Entry<String, ?> entry : refreshableServices.entrySet() ) {
Object beanRef = entry.getValue();
if (beanRef instanceof IRefreshable) {
m_refreshableServices.add((IRefreshable)beanRef);
}
}
}
}

这种方法在集群应用程序中特别有效,其中许多应用程序服务器之一可能会更改配置,然后所有这些都需要注意。如果您想使用 JMX 作为触发更改的机制,那么您的 JMX bean 可以在其任何属性发生更改时广播到 JMS 主题。

关于java - 我可以在运行时替换 Spring bean 定义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4041300/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com