Configuration over JNDI in Spring Framework
From a certain point on, an application has to be configurable. Spring Framework has a nice auxiliary tool for this issue since the first version 0.9 , the class PropertyPlaceholderConfigurer
and since Spring Framework 3.1 the class PropertySourcesPlaceholderConfigurer.
When you start a Google search for PropertyPlaceholderConfigurer,
you will find many examples where the configuration items are saved in properties files. But in many Java enterprise applications, it is common that the configuration items are loaded over JNDI look ups. I'd like to demonstrate how the PropertyPlaceholderConfigurer
(before Spring Framework 3.1) and accordingly PropertySourcesPlaceholderConfigurer
(since Spring Framework 3.1) can help to ease the configuration over JNDI look ups in our application.
Initial Situation
We have an web application that has a connection to a database. This database connection has to be configurable. The configuration items are defined in a web application context file.
context.xml
1<Context docBase="/opt/tomcat/warfiles/jndi-sample-war.war" antiResourceLocking="true">
2 <Environment name="username" value="demo" type="java.lang.String" override="false"/>
3 <Environment name="password" value="demo" type="java.lang.String" override="false"/>
4 <Environment name="url" value="jdbc:mysql://192.168.56.101:3306/wicket_demo" type="java.lang.String" override="false"/>
5</Context>
For loading these configuration items, the JNDI look up mechanism is used. In our application we define a data source bean in a Spring context XML file. This bean represents the database connection.
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5 http://www.springframework.org/schema/context
6 http://www.springframework.org/schema/context/spring-context.xsd">
7
8 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
9 destroy-method="close">
10 <property name="url" value="${url}" />
11 <property name="username" value="${username}" />
12 <property name="password" value="${password}" />
13 <bean>
14</beans>
Every value that starts and ends with ${}
should be replaced by PropertyPlaceholderConfigurer
and accordingly PropertySourcesPlaceholderConfigurer
at the time when launching the application. The next step is to set up PropertyPlaceholderConfigurer
and accordingly PropertySourcesPlaceholderConfigurer.
Before Spring Framework 3.1 - PropertyPlaceholderConfigurer
Set Up for JNDI Look Up
We define a PropertyPlaceholderConfigurer
bean in a Spring context XML file. This bean contains to an inner bean that maps the property names of the data source bean to the corresponding JNDI name. The JNDI name consists of two parts. The first part is the name of the context in which the resource is (in our case java:comp/env/
) and the second part is the name of the resource (in our case either username, password
or url).
1<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
2 <property name="properties">
3 <bean class="java.util.Properties">
4 <constructor-arg>
5 <map>
6 <entry key="username">
7 <jee:jndi-lookup jndi-name="java:comp/env/username" />
8 </entry>
9 <entry key="password">
10 <jee:jndi-lookup jndi-name="java:comp/env/password" />
11 </entry>
12 <entry key="url">
13 <jee:jndi-lookup jndi-name="java:comp/env/url" />
14 </entry>
15 </map>
16 </constructor-arg>
17 </bean>
18 </property>
19</bean>
Since Spring Framework 3.1 - PropertySourcesPlaceholderConfigurer
Set Up for JNDI Look Up
Since Spring 3.1 PropertySourcesPlaceholderConfigurer
should be used instead of PropertyPlaceholderConfigurer.
This effects that since Spring 3.1 the context:property-placeholder/ namespace element registers an instance of PropertySourcesPlaceholderConfigurer
(the namespace definition must be spring-context-3.1.xsd) instead of PropertyPlaceholderConfigurer
(you can simulate the old behaviour when you use the namespace definition spring-context-3.0.xsd). So our Spring XML context configuration is very short, when you comply some convention (based on the principle Convention over Configuration).
1<context:property-placeholder/>
The default behavior is that the PropertySourcesPlaceholderConfigurer
iterates through a set of [PropertySource](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/PropertySource.html "JavaDoc PropertySource")
to collect all properties values. This set contains JndiPropertySource
per default in a Spring based web application. By default, JndiPropertySource
looks up after JNDI resource names prefixed with java:comp/env
. This means if your property is ${url}
, the corresponding JNDI resource name has to be java:comp/env/url
. The source code of the sample web application is hosted on GitHub.