I am a Java expert with many years of developing applications and systems. I love learning new stuff and passing whatever I know to others. I love clean code, TDD and the simplest design possible. Eyal is a DZone MVB and is not an employee of DZone and has posted 23 posts at DZone. You can read more from them at their website. View Full User Profile

Spring Context with Properties, Collections and Maps

01.23.2014
| 4655 views |
  • submit to reddit

In this post I want to show how I added the XML context file to the Spring application.
The second aspect I will show will be the usage of the properties file for the external constants values.

All of the code is located at: https://github.com/eyalgo/request-validation (as previous posts).

I decided to do all the wiring using XML file and not annotation for several reasons:

  1. I am simulating a situation were the framework is not part of the codebase (it’s an external library) and it is not annotated by anything
  2. I want to emphasize the modularity of the system using several XML files (yes. I know it can be done using @Configuration)
  3. Although I know Spring, I still feel more comfortable having more control using the XML files
  4. For Spring newbies, I think they should start using XML configuration files and only when grasp the idea and technology, should start using annotation

About the modularization and how the sample app is constructed, I will expand in later post.

Let’s start with the properties file:
And here’s part of the properties file:

flag.external = EXTERNAL
flag.internal = INTERNAL
flag.even = EVEN
flag.odd = ODD
validation.acceptedIds=flow1,flow2,flow3,flow4,flow5
filter.external.name.max = 10
filter.external.name.min = 4
filter.internal.name.max = 6
filter.internal.name.min = 2

Properties File Location
We also need to tell Spring the location of our property file.
You can use PropertyPlaceholderConfigurer , or you can use the context element as shown here:

<context:property-placeholder location="classpath:spring/flow.properties" />

Simple Bean Example
This is the very basic example of how to create a bean

<bean id="evenIdFilter"
class="org.eyal.requestvalidation.flow.example.flow.itemsfilter.filters.EvenIdFilter">
</bean>

Using Simple Property
Suppose you want to add a property attribute to your bean.
I always use constructor injection, so I will use constructor-arg in the bean declaration.

<bean id="longNameExternalFilter"
class="org.eyal.requestvalidation.flow.example.flow.itemsfilter.filters.NameTooLongFilter">
<constructor-arg value="${filter.external.name.max}" />
</bean>

List Example
Suppose you have a class that gets a list (or set) of objects (either another bean class, or just Strings).
You can add it as a parameter in the constructor-arg, but I prefer to create the list outside the bean declaration and refer to it in the bean.
Here’s how:

<util:list id="defaultFilters">
<ref bean="emptyNameFilter" />
<ref bean="someOtherBean" />
</util:list>

And

<bean id="itemFiltersMapperByFlag"
class="org.eyal.requestvalidation.flow.itemsfilter.ItemFiltersMapperByFlag">
<constructor-arg ref="defaultFilters" />
<constructor-arg ref="filtersByFlag" />
</bean>

Collection of Values in the Properties File
What if I want to set a list (set) of values to pass a bean.
Not a list of beans as described above.
The in the properties file I will put:
validation.acceptedIds=flow1,flow2,flow3,flow4,flow5

And in bean:

<bean id="acceptedIdsValidation"
class="org.eyal.requestvalidation.flow.example.flow.requestvalidation.validations.AcceptedIdsValidation">
<constructor-arg value="#{'${validation.acceptedIds}'.split(',')}" />
</bean>

See how I used Spring Expression Language (SpEL)

Map Injection Example
Here’s a sample of an empty map creation:

<util:map id="validationsByFlag">
</util:map>

Here’s a map with some entries.
See how the keys are also set from the properties file.

<util:map id="filtersByFlag">
<entry key="${flag.external}" value-ref="filtersForExternal" />
<entry key="${flag.internal}" value-ref="filtersForInternal" />
<entry key="${flag.even}" value-ref="filtersForEven" />
<entry key="${flag.odd}" value-ref="filtersForOdd" />
</util:map>


In the map example above we have keys as Strings from the properties file.
The values are reference to other beans as described above.

The usage would be the same as for list:

<bean id="itemFiltersMapperByFlag"
class="org.eyal.requestvalidation.flow.itemsfilter.ItemFiltersMapperByFlag">
<constructor-arg ref="defaultFilters" />
<constructor-arg ref="filtersByFlag" />
</bean>

Conclusion
In this post I showed some basic examples of Spring configuration using XML and properties file.
I strongly believe that until the team is not fully understand the way Spring works, everyone should stick with this kind of configuration.
If you find that you start to get files, which are too big, then you may want to check your design. Annotations will just hide your poorly design system.

Published at DZone with permission of Eyal Golan, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)