Fork me on GitHub

Spring Registry Component


The Spring registry is a single source of external configuration for Spring components and applications. It can be used by components to source configuration, knowing that it can be used from within applications without the information being hard coded into the component.

To facilitate a variety of providers, Commons Configuration is used to implement the backing storage.

This relies on a pull-based (or lookup) mechanism - the applications request specific pieces of configuration at the time they need them, and it is retrieved from the registry.

The registry is configurable so that configuration can be placed in any location desired, and is shared container wide. A registry using the same file as other running VMs should operate correctly.

Inside the application server, this means that the scope is application wide as each application has it’s own container. It may be feasible to provide a single registry for the whole server, but this has not yet been tested. This would only be necessary if the server was to dictate configuration locations that the registry was not already configured to use. Of course, such additional locations could be added to the application registry instances programmatically as well.

Example Configuration

      <jndi prefix="java:comp/env" config-optional="true"/>
      <xml fileName="${user.home}/.m2/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva"
           config-at="org.apache.maven.archiva" config-forceCreate="true"/>
      <properties fileName="${user.home}/.m2/" config-optional="true"

The configuration inside the outer properties element is equivalent to the builder syntax for Commons Configuration. This maps to similar concepts in the registry.

In this example, the precedence is to first look in the system properties, then JNDI, then the given XML file, and finally the given properties file.

Registries can have 'sections', which are declared as partitioned areas of the registry. This is done using the config-name attribute in Commons Configuration. While the sections behave normally as a part of the global registry, they can easily be retrieved independently. This is particularly useful for write-back operations so the file the section is stored in can be saved when the registry is modified.

Each configuration source can be configured with a given mount-point in the registry using the config-at attribute. This will cause all of the properties to be stored with the given prefix.

Using the Registry

The registry can be used as a simple directory, for example:

int value = registry.getInt( "" );
String text = registry.getString( "" );
boolean enabled = registry.getBoolean( "system.enabled", true );

The first parameter is always a key. The registry is hierachical, so in the key, a . (period) represents a nested configuration, and can be traversed to any level.

The second parameter specifies a default value. If it is not given, then null is returned for strings if the key is not found in the registry, and an exception is thrown for integers and booleans under the same circumstances.

Subsets and Sections

There are two ways to work with a portion of the registry at a time: subsets and sections.

Sections were encountered earlier - and while they return a subset it may span a number of different base prefixes, depending on whether config-at was specified on the section or not. Even so, if it is a subset of the hierachy, some elements of the hierachy at the same level might not be returned because they come from a different section.

On the other hand, subsets are reductions of the registry to keys descending from a given prefix.

Once a subset (or section) is obtained, it behaves the same as the registry as a whole, however it will have fewer values, and looking up values will not have the prefix as a part of the key.

For example:

String value = registry.getString( "org.codehaus.plexus.registry.value" );
Registry subset = registry.getSubset( "org.codehaus.plexus.registry" );
value = subset.getString( "value" ); // this will equal the earlier value retrieved

Lists and Maps

It is also possible to retrieve subsets of the registry as collections.

  • getProperties(key): Maps and properties are straightforward - the subset is converted into key/value pairs and returned as a map.

  • getSubsetList(key): For lists of complex types that will still contain more than one key/value pair, this method can be used to retrieve them as a list of subset registries.

  • getList(key): For lists of simple types, this method can be used to get a list of value objects.

Using Models

To simplify the translation of configuration into reusable beans and to produce a self-documenting system, Modello can be used to generate registry I/O classes. The appropriate goals in the plugin are registry-reader and registry-writer.

Saving Changes

Saving changes to a registry is quite simple:;

Note that the registry must be a file-based section (saving the entire registry will not succeed). It will be saved to the same location that it was loaded from.

Adding Change Listeners