Using Configuration
Commons Configuration allows you to access configuration properties from
a variety of different sources. No matter if they are stored in a properties file,
a XML document, or a JNDI tree, they can all be accessed in the same way
through the generic Configuration
interface.
Another strength of Commons Configuration is its ability to mix configurations
from heterogeneous sources and treat them like a single logic configuration.
This section will introduce you to the different configurations
available and will show you how to combine them.
Configuration Sources
Currently there are quite a number of different sources of Configuration objects. But,
by just using a Configuration object versus a specific type like XMLConfiguration or
JNDIConfiguration, you are sheltered from the mechanics of actually retrieving the
configuration values. These various sources include:
-
PropertiesConfiguration
Loads configuration values from a properties file.
-
XMLConfiguration
Takes values from an XML document.
-
INIConfiguration
Loads the values from a .ini file as used by Windows.
-
PropertyListConfiguration
Loads values from an OpenStep .plist file. XMLPropertyListConfiguration is also
available to read the XML variant used by Mac OS X.
-
JNDIConfiguration
Using a key in the JNDI tree, can retrieve values as configuration properties.
-
BaseConfiguration
An in-memory method of populating a Configuration object.
-
HierarchicalConfiguration
An in-memory Configuration object that is able to deal with complex
structured data.
-
SystemConfiguration
A configuration using the system properties
-
ConfigurationConverter
Takes a java.util.Properties or an org.apache.commons.collections.ExtendedProperties
and converts it to a Configuration object.
Mixing Configuration Sources
Often you want to provide a base set of configuration values, but allow the user to easily
override them for their specific environment. Well one way is to hard code the default
values into your code, and have then provide a property file that overrides this. However,
this is a very rigid way of doing things. Instead, with the CompositeConfiguration
you can provide many different ways of setting up a configuration. You can either do it
manually:
CompositeConfiguration config = new CompositeConfiguration();
config.addConfiguration(new SystemConfiguration());
config.addConfiguration(new PropertiesConfiguration("application.properties"));
or via the ConfigurationFactory
class:
ConfigurationFactory factory = new ConfigurationFactory("config.xml");
Configuration config = factory.getConfiguration();
The config.xml
file used in the example above is a configuration descriptor,
it specifies the Configuration objects to load. Here is an example of descriptor:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<configuration>
<system/>
<properties fileName="application.properties"/>
</configuration>
What this says is that we are loading up all system properties, as well as the properties
file application.properties
. The order of precedence is first to last. So in
the above example, if a property is not found in the system properties, it'll be searched
in the properties file. This allows you to set up default values in a properties file, and
override them with the system properties.
The Configuration interface
All the classes in this package that represent different kinds of configuration
sources share a single interface:
Configuration
.
This interface allows you to access and manipulate configuration properties
in a generic way.
A major part of the methods defined in the Configuration
interface deals with retrieving properties of different data types. All
these methods take a key as an argument that points to the desired
property. This is a string value whose exact meaning depends on the
concrete Configuration
implementation used. They try to
find the property specified by the passed in key and convert it to their
target type; this converted value will be returned. There are also
overloaded variants of all methods that allow to specify a default value,
which will be returned if the property cannot be found. The following
data types are supported:
- BigDecimal
- BigInteger
- boolean
- byte
- double
- float
- int
- long
- short
- String
The names of these methods start with get
followed by their
data type. The getString()
method for instance will return
String values, getInt()
will operate on integers.
Properties can have multiple values, so it is also possible to query a
list containing all of the available values. This is done using the
getList()
method.
For manipulating properties or their values the following methods can
be used:
addProperty()
- Adds a new property to the configuration. If this property already
exists, another value is added to it (so it becomes a multi-valued
property).
clearProperty()
- Removes the specified property from the configuration.
setProperty()
- Overwrites the value of the specified property. This is the same
as removing the property and then calling
addProperty()
with the new property value.
clear()
- Wipes out the whole configuration
Threading issues
The most concrete implementations of the Configuration
interface that are shipped with this library are not thread-safe.
They can be accessed concurrently in a read-only manner. However if one
thread modifies a configuration object, manual synchronization has to be
performed to ensure correctness of data. Notes about the thread
safety of concrete implementation classes can be found in the Javadocs
for these classes.