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
<Context docBase="/opt/tomcat/warfiles/jndi-sample-war.war" antiResourceLocking="true"> <Environment name="username" value="demo" type="java.lang.String" override="false"/> <Environment name="password" value="demo" type="java.lang.String" override="false"/> url" value="jdbc:mysql://localhost:3306/wicket_demo" type="java.lang.String" override="false"/> </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.
<?xml version="1.0" encoding="UTF-8"?> xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <!--<span class="hiddenSpellError" pre="" data-mce-bogus="1"-->bean> </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).
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="properties"> <bean class="java.util.Properties"> <constructor-arg> <map> <entry key="username"> <jee:jndi-lookup jndi-name="java:comp/env/username" /> </entry> <entry key="password"> <jee:jndi-lookup jndi-name="java:comp/env/password" /> </entry> <entry key="url"> <jee:jndi-lookup jndi-name="java:comp/env/url" /> </entry> </map> </constructor-arg> </bean> </property> </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).
<context:property-placeholder/>
The default behavior is that the PropertySourcesPlaceholderConfigurer iterates through a set of 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.
Reference: | Configuration over JNDI in Spring Framework from our JCG partner Sandra Parsick at the SKM IT WORLD blog. |