Spring Context with Properties, Collections and Maps
Join the DZone community and get the full member experience.
Join For FreeIn 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:
- 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
- I want to emphasize the modularity of the system using several XML files (yes. I know it can be done using @Configuration)
- Although I know Spring, I still feel more comfortable having more control using the XML files
- 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, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments