簡體   English   中英

如何用Spring重新加載屬性?

[英]How to reload properties with Spring?

我正在使用Spring 3的屬性文件。當Spring初始化它的上下文時,它會加載屬性文件並將其放在所有帶有@Value注釋的bean中。

我希望有可能更新文件中的某些屬性,並在服務器上公開JMX,將新屬性重新加載到Spring - 無需重新啟動服務器,並重新加載其上下文。

我可以通過使用一些Spring方法重新加載屬性並將它們填充到所有bean來實現它,或者我應該自己寫這樣的東西嗎?

我建議用Apache Commons Configuration項目java.util.PropertiesPropertiesConfiguration替換java.util.Properties 它通過檢測文件何時更改或通過JMX觸發來支持自動重新加載。

我認為沒有共同的方法可以做到這一點。 最“干凈”的是關閉Spring上下文並從頭開始構建它。 例如,考慮使用DBCP連接池並更新其數據庫連接URL。 這意味着必須正確關閉池,然后必須創建新對象,然后還必須更新對池的所有引用。 現在,一些bean可能從該池獲取連接,並且更新池配置意味着您需要以某種方式重新請求連接。 因此,bean可能需要知道如何做到這一點,這是不常見的。

我建議使用配置和更新事件創建單獨的bean,並將該bean作為依賴關系,以便了解有關配置更改的所有bean。 然后,您可以使用Apache Commons Configuration來獲取文件更改並傳播配置更新。

也許使用JMS是好的(如果你以后去分發你的應用程序)。

是的,你可以用Spring JMX的方式做到這一點。 將這些bean添加到spring配置文件中。 創建一個單獨的方法來讀取屬性文件。 在這個例子中,我使用callThisAgain()方法。

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
        <map>
            <entry key="your.package.bean:name=sampleBeanService" value-ref="sampleService"/>
        </map>
    </property>
    <property name="assembler">
        <bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
            <property name="managedMethods">
                <value>
                    callThisAgain <!--Simply declare the method name here (only the name) -->
                </value>
            </property>
        </bean>
    </property>
</bean>

<bean class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="rmiRegistry">
    <property name="objectName" value="connector:name=rmi"/>
    <property name="serviceUrl" value="service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:11000/sample"/>
</bean>

<bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
    <property name="port" value="11000"/>
</bean>

之后,您可以使用jconsole重新加載方法,而無需重新啟動服務器。

Apache為我們提供了使用可重載屬性文件的實用程序。

<bean id="propertiesReloadingStrategy" class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy">
    <property name="refreshDelay" value="30000" /> <!-- 30 seconds -->
</bean>

<bean id="reloadableProperties" class="org.apache.commons.configuration.PropertiesConfiguration">
    <constructor-arg value="file:/web/${weblogic.Domain}/${weblogic.Name}/${app.Name}/reloadable_cfg/Reloadable.properties"/>
    <property name="reloadingStrategy" ref="propertiesReloadingStrategy"/>
</bean>

使用與spring相同的apache如下:

@Component
public class ApplicationProperties {
    private PropertiesConfiguration configuration;

    @PostConstruct
    private void init() {
        try {
            String filePath = "/opt/files/myproperties.properties";
            System.out.println("Loading the properties file: " + filePath);
            configuration = new PropertiesConfiguration(filePath);

            //Create new FileChangedReloadingStrategy to reload the properties file based on the given time interval
            FileChangedReloadingStrategy fileChangedReloadingStrategy = new FileChangedReloadingStrategy();
           fileChangedReloadingStrategy.setRefreshDelay(60*1000);
            configuration.setReloadingStrategy(fileChangedReloadingStrategy);
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }
    }

    public String getProperty(String key) {
        return (String) configuration.getProperty(key);
    }

    public void setProperty(String key, Object value) {
        configuration.setProperty(key, value);
    }

    public void save() {
        try {
            configuration.save();
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }
    }
}

雖然這里的一些人建議使用外部方式來使用屬性(在Spring自己使用屬性文件的方式之外)。 這個答案正是您在Spring Boot和Java EE中尋找的https://stackoverflow.com/a/52648630/39998熱重新加載屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM