Spring有一个很好的机制PropertyPlaceholderConfigurer,用于将值,例如timeouts,JDBC Urls等注入Spring bean以进行配置。是否有一种合理的方法来处理可在运行时更改的配置值?
更新:使用Spring 3.1,有一种很好的方法可以通过PropertySource包含非静态配置源,例如数据库。一些ApplicationContexts提供了一种原则上能够处理不断变化的配置值的刷新机制。然而,它首先停止应用程序,然后创建所有bean新鲜,然后再次启动应用程序上下文。但是,出于我们的目的,我需要一种方法来透明地执行此操作,以便服务器正确处理当前正在运行的请求。
执行此操作的另一个想法是在配置更改时创建新对象的自定义Scope。遗憾的是,提供给Scope的ObjectFactory使用了预处理的bean定义,因此不会从配置中重新读取占位符。因此,创建的对象具有相同的配置。 : - (
答案 0 :(得分:2)
不幸的是,来自properties
文件的配置是静态的,并且在启动时发生。我通常做的是通过jmx公开动态属性:
@ManagedResource
@Service
public class BusinessService {
@ManagedAttribute
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void businessMethod() {
//use age...
}
}
请记住添加:
<context:mbean-export/>
到您的配置。现在,您可以通过jconsole
或任何其他JMX客户端访问和更改该属性。另见:23.3.2 Using Source-Level Metadata (JDK 5.0 annotations)。
答案 1 :(得分:2)
以下是有点奇怪但有效。您创建一个名为reconfigurable
的{{3}},只要发生配置更新,就会抛弃在该范围内创建的所有bean。因此,在配置更改后将创建一个新bean。
必须通过spring表达式语言检索实际配置值,因为普通$ {}语法和PropertyOverrideConfigurer的值似乎都在BeanDefinition中永久修复。具有可重新配置属性someProperty
的bean的bean声明如下所示:
<bean class="blablu.Testbean" scope="reconfigurable"
p:someProperty="#{ config['configexplicit']}">
<aop:scoped-proxy />
</bean>
您需要使用aop:scoped-proxy,以便使用此bean的bean始终从自定义作用域中检索最新配置的bean。
使用@Value
声明属性也有效;如果使用组件扫描,则需要使用注释声明范围
@Scope(value="reconfigurableScope", proxyMode=ScopedProxyMode.TARGET_CLASS)
如果您关心细节:范围的基本概念是:
public class ReconfigurableScope implements Scope {
private final Map<String, Object> nameToObjectMap = new ConcurrentHashMap<String, Object>();
public Object get(final String name, final ObjectFactory<?> objectFactory) {
Object bean = nameToObjectMap.get(name);
if (null == bean) {
bean = objectFactory.getObject();
nameToObjectMap.put(name, bean);
}
return bean;
}
// called from outside on each configuration change
public void update(final ConfigurationObservable observable, final Object arg) {
nameToObjectMap.clear();
}
}
加上一些线程安全和清理的东西:删除的bean需要稍后销毁,并且应用程序上下文关闭。
答案 2 :(得分:1)
有一个正在运行的例子,说明你要在这里完成的任务:https://github.com/ldojo/spring-cloud-config-examples
它演示了Spring Cloud Config Server和客户端服务如何通过Spring Cloud Bus进行通信,并且当Config Server的repo中发生配置更改时,客户端的配置属性可以在运行时更改。
答案 3 :(得分:0)
对于有效的运行时重新配置,您可以使用spring的Cloud Config项目。在这种安排中,您将拥有一个Configuration Repository
,比如一个git存储库,其中包含您的配置值。然后将Configuration Server
放在该存储库的前面。只要对支持存储库发生推送,就会更新此服务器。最后,您的应用程序将是Config Server
的客户端,并从中获取新的配置。查看Spring Cloud了解详情。