进一步更新的答案涵盖了脚本豆
spring 2.5.x +支持的另一种方法是脚本化bean。您可以为脚本使用多种语言-BeanShell可能是最直观的,因为它与Java具有相同的语法,但是它确实需要一些外部依赖关系。但是,示例在Groovy中。
Spring文档的24.3.1.2节介绍了如何配置此方法,但以下是一些重要摘录,这些摘录说明了我为使它们更适合您的情况而编辑的方法:
<beans>
<!-- This bean is now 'refreshable' due to the presence of the 'refresh-check-delay' attribute -->
<lang:groovy id="messenger"
refresh-check-delay="5000" <!-- switches refreshing on with 5 seconds between checks -->
script-source="classpath:Messenger.groovy">
<lang:property name="message" value="defaultMessage" />
</lang:groovy>
<bean id="service" class="org.example.DefaultService">
<property name="messenger" ref="messenger" />
</bean>
</beans>
Groovy脚本如下所示:
package org.example
class GroovyMessenger implements Messenger {
private String message = "anotherProperty";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message
}
}
由于系统管理员想要进行更改,因此他们(或您)可以适当地编辑脚本的内容。该脚本不是已部署应用程序的一部分,可以引用一个已知文件位置(或在启动过程中通过标准PropertyPlaceholderConfigurer配置的文件位置)。
尽管该示例使用了Groovy类,但是您可以让该类执行读取简单属性文件的代码。以这种方式,您永远不会直接编辑脚本,只需触摸它即可更改时间戳。然后,该操作将触发重新加载,进而从(更新的)属性文件中触发属性的刷新,该文件最终将在Spring上下文中更新值,然后关闭。
文档确实指出该技术不适用于构造函数注入,但是您可以解决该问题。
更新了答案以涵盖动态属性更改
从这篇文章引用,它提供了完整的源代码,一种方法是:
* a factory bean that detects file system changes
* an observer pattern for Properties, so that file system changes can be propagated
* a property placeholder configurer that remembers where which placeholders were used, and updates singleton beans’ properties
* a timer that triggers the regular check for changed files
观察者模式由接口和类ReloadableProperties,ReloadablePropertiesListener,PropertiesReloadedEvent和ReloadablePropertiesBase实现。它们都不是特别令人兴奋的,只是正常的侦听器处理。DelegatingProperties类用于在更新属性时透明地交换当前属性。我们只一次更新整个属性映射,以便应用程序可以避免不一致的中间状态(稍后将对此进行详细介绍)。
现在,可以编写ReloadablePropertiesFactoryBean来创建ReloadableProperties实例(而不是像PropertiesFactoryBean一样的Properties实例)。当提示您这样做时,RPFB将检查文件修改时间,并在必要时更新其ReloadableProperties。这触发了观察者模式机制。
在我们的示例中,唯一的侦听器是ReloadingPropertyPlaceholderConfigurer。它的行为就像标准的Spring PropertyPlaceholderConfigurer一样,只是它会跟踪占位符的所有用法。现在,当重新加载属性时,将找到每个修改后的属性的所有用法,并再次分配那些单例bean的属性。
以下是涵盖静态属性更改的原始答案:
听起来您只是想将外部属性注入到Spring上下文中。该PropertyPlaceholderConfigurer
设计用于此目的:
<!-- Property configuration (if required) -->
<bean id="serverProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- Identical properties in later files overwrite earlier ones in this list -->
<value>file:/some/admin/location/application.properties</value>
</list>
</property>
</bean>
然后,您可以使用Ant语法占位符(如果您希望从Spring 2.5.5开始,可以嵌套使用)来引用外部属性。
<bean id="example" class="org.example.DataSource">
<property name="password" value="${password}"/>
</bean>
然后,确保只有管理员用户和运行该应用程序的用户才能访问application.properties文件。
示例application.properties:
密码=土豚
configuration
需要在运行时更新Bean-还是每次管理员更改值时都需要更新Bean?我那个你的问题吗?还是要DataSource
/MailSender
bean在运行时使用更新的配置?还是两者?