The issue:
Our webapp is using a spring and hibernate backend, and both spring configuration and Java classes need to access database connection properties.
Currently there is an
application.properties
file and a spring applicationContext.xml
, both
which contain the same information for the database connection. Ideally,
there should be only one configuration file to define the properties, which is
used by both spring and Java.Spring has the ability to load
properties files as part of the application configuration, for use internally.
The properties can be referenced within spring configuration files using
ant-style placeholders, e.g. ${app.var}
. To solve our issue though we'll
also need to provide a populated bean that can be used by our production
classes. Here's the properties file (application.properties
):
appl.name=My Web Application
appl.home=/Users/webapp/application/
# Database properties
db.driver=org.hsqldb.jdbcDriver
db.name=v8max.db
db.url=jdbc:hsqldb:file://${appl.home}/database/${db.name}
db.user=SA
db.pass=
Spring loads the properties file using a bean of the type
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
, and then we can reference the properties directly in the spring configuration
file. Note that we can also use placeholders within the properties file, as
in the db.url above - the PropertyPlaceholderConfigurer
will resolve them too!
So now we've removed the need to have literals in the spring config!
Exposing the spring properties bean in java
To allow our Java classes to
access the properties from the same object as spring, we'll need to extend the
PropertyPlaceholderConfigurer
so that we can provide a more convenient method
for retrieving the properties (there is no direct method of retrieving
properties!). We can extend the spring provided class to allow us to reuse
spring's property resolver in our Java classes:
If we now update the applicationProperties
bean to use the PropertiesUtil
class, we can use the static getProperty method to access the resolved
properties via the same object as the spring configuration bean. Of course,
we could run into problems if a class tries to use PropertiesUtil
before the
spring context has been initialised. For example if you're registering
ServletContextListeners
in your web.xml
before configuring spring, you'll get
a NullPointerException
if one of those classes tries to use PropertiesUtil
.
For that reason I've had to declare the spring context before any context
listeners.
References
http://www.jdocs.com/spring/1.2.8/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html 1. http://j2eecookbook.blogspot.com/2007/07/accessing-properties-loaded-via-spring.html