Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Further updated answer to cover scripted bean</strong></p> <p>Another approach supported by spring 2.5.x+ is that of the scripted bean. You can use a variety of languages for your script - BeanShell is probably the most intuitive given that it has the same syntax as Java, but it does require some external dependencies. However, the examples are in Groovy. </p> <p>Section 24.3.1.2 of the <a href="http://static.springsource.org/spring/docs/2.0.x/reference/dynamic-language.html" rel="nofollow">Spring Documentation</a> covers how to configure this, but here are some salient excerpts illustrating the approach which I've edited to make them more applicable to your situation:</p> <pre><code>&lt;beans&gt; &lt;!-- This bean is now 'refreshable' due to the presence of the 'refresh-check-delay' attribute --&gt; &lt;lang:groovy id="messenger" refresh-check-delay="5000" &lt;!-- switches refreshing on with 5 seconds between checks --&gt; script-source="classpath:Messenger.groovy"&gt; &lt;lang:property name="message" value="defaultMessage" /&gt; &lt;/lang:groovy&gt; &lt;bean id="service" class="org.example.DefaultService"&gt; &lt;property name="messenger" ref="messenger" /&gt; &lt;/bean&gt; &lt;/beans&gt; </code></pre> <p>With the Groovy script looking like this:</p> <pre><code>package org.example class GroovyMessenger implements Messenger { private String message = "anotherProperty"; public String getMessage() { return message; } public void setMessage(String message) { this.message = message } } </code></pre> <p>As the system administrator wants to make changes then they (or you) can edit the contents of the script appropriately. The script is not part of the deployed application and can reference a known file location (or one that is configured through a standard PropertyPlaceholderConfigurer during startup). </p> <p>Although the example uses a Groovy class, you could have the class execute code that reads a simple properties file. In that manner, you never edit the script directly, just touch it to change the timestamp. That action then triggers the reload, which in turn triggers the refresh of properties from the (updated) properties file, which finally updates the values within the Spring context and off you go.</p> <p>The documentation does point out that this technique doesn't work for constructor-injection, but maybe you can work around that.</p> <p><strong>Updated answer to cover dynamic property changes</strong></p> <p><a href="http://www.wuenschenswert.net/wunschdenken/archives/127" rel="nofollow">Quoting from this article</a>, which <a href="http://www.wuenschenswert.net/files/spring-reloaded-2007-04-11.zip" rel="nofollow">provides full source code</a>, one approach is:</p> <blockquote> <pre><code>* 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 </code></pre> <p>The observer pattern is implemented by the interfaces and classes ReloadableProperties, ReloadablePropertiesListener, PropertiesReloadedEvent, and ReloadablePropertiesBase. None of them are especially exciting, just normal listener handling. The class DelegatingProperties serves to transparently exchange the current properties when properties are updated. We only update the whole property map at once, so that the application can avoid inconsistent intermediate states (more on this later).</p> <p>Now the ReloadablePropertiesFactoryBean can be written to create a ReloadableProperties instance (instead of a Properties instance, as the PropertiesFactoryBean does). When prompted to do so, the RPFB checks file modification times, and if necessary, updates its ReloadableProperties. This triggers the observer pattern machinery.</p> <p>In our case, the only listener is the ReloadingPropertyPlaceholderConfigurer. It behaves just like a standard spring PropertyPlaceholderConfigurer, except that it tracks all usages of placeholders. Now when properties are reloaded, all usages of each modified property are found, and the properties of those singleton beans are assigned again.</p> </blockquote> <p><strong>Original answer below covering static property changes:</strong></p> <p>Sounds like you just want to inject external properties into your Spring context. The <code>PropertyPlaceholderConfigurer</code> is designed for this purpose:</p> <pre><code> &lt;!-- Property configuration (if required) --&gt; &lt;bean id="serverProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt; &lt;property name="locations"&gt; &lt;list&gt; &lt;!-- Identical properties in later files overwrite earlier ones in this list --&gt; &lt;value&gt;file:/some/admin/location/application.properties&lt;/value&gt; &lt;/list&gt; &lt;/property&gt; &lt;/bean&gt; </code></pre> <p>you then reference the external properties with Ant syntax placeholders (that can be nested if you want from Spring 2.5.5 onwards)</p> <pre><code> &lt;bean id="example" class="org.example.DataSource"&gt; &lt;property name="password" value="${password}"/&gt; &lt;/bean&gt; </code></pre> <p>You then ensure that the application.properties file is only accessible to the admin user and the user running the application.</p> <p>Example application.properties:</p> <p>password=Aardvark</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload