{"id":107,"date":"2006-12-24T14:17:56","date_gmt":"2006-12-24T12:17:56","guid":{"rendered":"http:\/\/www.wuenschenswert.net\/wunschdenken\/archives\/107"},"modified":"2007-04-18T08:47:43","modified_gmt":"2007-04-18T06:47:43","slug":"spring-configuration-properties-defaults-and-reloading","status":"publish","type":"post","link":"http:\/\/www.wuenschenswert.net\/wunschdenken\/archives\/107","title":{"rendered":"Spring configuration properties: Defaults and Reloading"},"content":{"rendered":"<p>We&#8217;re using the <a href=\"http:\/\/www.springframework.org\/\">spring framework<\/a> a lot at work, and it&#8217;s generally an enormous improvement over our diverse previous practices for configuration and inter-component relations. However, there are two points where Spring seemed to be a step backwards compared to our previous practice, so I set out to fix them. I hope this will be interesting to others as well &#8211; this be my christmas gift&#8230;<\/p>\n<h3>Default values<\/h3>\n<p>Using Spring&#8217;s PropertyPlaceholderConfigurer, we separate the configuration of our software into an XML file containing the detailed wiring, and a standard Java Properties file containing simple parameters that can be adjusted by customers (such as cache sizes, TCP\/IP port numbers, database connect strings, authentication names and passwords).<\/p>\n<p>Now let&#8217;s assume some customer has adapted the properties file, while we ship a new version of our software, which introduces new configuration parameters. The customer shouldn&#8217;t have to manually merge and extend his property file; instead, the XML file contains reasonable default values for those properties missing from the customer&#8217;s properties file.<\/p>\n<p>In out-of-the-box Spring, there are two ways to do this with a PropertyPlaceholderConfigurer: either put a list of default property bindings into the XML file itself, or put them into another Properties file, which may be contained as a resource in the jar file. <a href=\"http:\/\/www.kleineikenscheidt.de\/stefan\/archives\/2005\/06\/default-configuration-with-spring.html\">Stefan Kleineikenscheidt<\/a> has a good description of this approach.<\/p>\n<p>What I found somewhat inconvenient is that each property name is listed twice: once in the default values, once when it is assigned to some bean property. So here&#8217;s how Stefan&#8217;s example would look using my <a href=\"http:\/\/www.wuenschenswert.net\/files\/DefaultPropertyPlaceholderConfigurer.java\">DefaultPropertyPlaceholderConfigurer<\/a>:<\/p>\n<pre>\r\n&lt;bean id=\"propertyConfigurer\"\r\n    class=\"net.wuenschenswert.spring.DefaultPropertyPlaceholderConfigurer\">\r\n  &lt;property name=\"location\" value=\"file:custom\/my.properties\"\/>\r\n&lt;\/bean>\r\n\r\n&lt;bean id=\"mybean\">\r\n  &lt;property name=\"cachesize\" value=\"${my.cache.size=100}\"\/>\r\n&lt;\/bean>\r\n<\/pre>\n<p>What happens here? The property configurer will load the properties from the given location as usual. Then when it comes to replacing a placeholder, and that placeholder is not defined in the properties file, the default value specified after the equals sign is used!<\/p>\n<pre>\r\n  ${<i>placeholder<\/i>=<i>defaultvalue<\/i>}\r\n<\/pre>\n<h3>Reloading properties<\/h3>\n<p>When loading configuration properties from a file, our software would regularly check whether the file&#8217;s modification date has changed, and reload the properties if necessary.<\/p>\n<p>I&#8217;ll go into this more deeply into the next post&#8230; until then, I&#8217;ll give you the syntax:<\/p>\n<pre>\r\n&lt;bean id=\"configproperties\" \r\n     class=\"net.wuenschenswert.spring.reconfiguration.ReloadablePropertiesFactoryBean\">\r\n  &lt;property name=\"location\" value=\"file:custom\/my.properties\"\/>\r\n&lt;\/bean>\r\n\r\n&lt;bean id=\"propertyConfigurer\" \r\n     class=\"net.wuenschenswert.spring.reconfiguration.ReloadingPropertyPlaceholderConfigurer\">\r\n  &lt;property name=\"properties\" ref=\"configproperties\"\/>\r\n&lt;\/bean>\r\n\r\n&lt;bean id=\"mybean\">\r\n  &lt;property name=\"cachesize\" value=\"#{my.cache.size=100}\"\/>\r\n&lt;\/bean>\r\n<\/pre>\n<p>The hash mark identifies the property as reloadable; When the file changes, and the value of the property my.cache.size defined inside that file changes, the setter for the cacheSize property is invoked on the singleton bean named &#8220;mybean&#8221;. Of course this includes default values, as above.<\/p>\n<pre>\r\n  #{<i>reloadableplaceholder<\/i>}\r\n  #{<i>reloadableplaceholder<\/i>=<i>defaultvalue<\/i>}\r\n<\/pre>\n<p>And it actually works!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re using the spring framework a lot at work, and it&#8217;s generally an enormous improvement over our diverse previous practices for configuration and inter-component relations. However, there are two points where Spring seemed to be a step backwards compared to our previous practice, so I set out to fix them. I hope this will be &hellip; <a href=\"http:\/\/www.wuenschenswert.net\/wunschdenken\/archives\/107\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Spring configuration properties: Defaults and Reloading&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[],"_links":{"self":[{"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/posts\/107"}],"collection":[{"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/comments?post=107"}],"version-history":[{"count":0,"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/posts\/107\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/media?parent=107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/categories?post=107"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.wuenschenswert.net\/wunschdenken\/wp-json\/wp\/v2\/tags?post=107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}