I'm Solomon Duskis, NYC consultant and a Java/J2EE guy. I work at Sungard Consulting Services in NYC. The postings on this site are my own and do not necessarily represent the positions, strategies or opinions of my employer. Solomon is a DZone MVB and is not an employee of DZone and has posted 22 posts at DZone. You can read more from them at their website. View Full User Profile

Spring EL - Environmental Configuration and Cleaner XML

03.31.2010
| 9808 views |
  • submit to reddit

I'd like to share Spring EL (SpEL) tips that I've used for 1) annotation friendly, modularized environmental configuration 2) cleaner XML configuration. This is far from a comprehensive tutorial, simply a couple of tips may be useful.

Purpose

I used Spring 2.5 annotations when they first came out, but had a hard time figuring out how to leverage Spring's externalized configuration capabilities in an annotation heavy system. It wasn't just me; Spring 2.5 left a virtual void between annotation driven development and that excellent externalized configuration. The Spring folks realized that, and created SpEL to fill that void. I was able to use SpEL over the last couple of weeks to configure my application. I knew that SpEL was nice, but up until my first real use, I didn't realize how nice it was.

Beyond being able to inject environment specific configuration into annotations, I found some additional benefits:

  1. richer, object-based configuration option (rather than a String based configuration)
  2. reduced XML file size.

Environmental Concerns

How do you inject environment specific values in an annotation driven world? We needed to configure environment specific URLs, other strings and some proxies into my Controllers and Daos. We created a file "spring-environment.xml" that contained all of that stuff, and allowed that file to be changed per environment. Here's what our XML configuration looks like:

<util:map id="foo">
  <entry key="urlTemplate">
     <value>http://somwhere.com/foo?bar=baz&amp;bap={replaceMe}</value>
  </entry>
  <entry key="proxy" value-ref="proxy1" />
</util:map>
  

The annotated code that used it looked something like this:

@Repository
public class HttpFooDAO extends HttpRetriever implements FooDao {

  @Autowired
  public HttpFooDAO(
    @Value("#{foo.urlTemplate"} String urlTemplate,
    @Value("#{foo.proxy}") Proxy proxy )
      super(urlTemplate, proxy);
  )

  public Foo getFoo(String me){
    String s = super.retrieve(me);
    // custom parser
  }
}

Modularization

Why use <util:map>?

Initially, we were thinking of creating constants and individual beans. We decided to use <util:map > for two reasons:

  1. Spring doesn't implement constants as first class citizens.
  2. <util:map> allowed us to modularize configuration concerns

Pre Spring 3.0, I was on projects where we had dozens of configure lines with seemingly random concerns. We could have created multiple property files, but that option was more difficult on the operational folks. Intra-file logical partitioning was possible with # comments and careful management, but that required everyone across a long running project to adhere to the conventions based on an honor system. In other words, over time, the conventions fell by the wayside.

In Spring 3.0, the <util:map> paradigm allowed us to engineer configuration modularity in a single file. Hopefully, our project will be around in two years, and the engineers who enhance they system will be more likely to the more explicit conventions.

One file per deployment environment

We also built a number of other files to support production/qa/other environments. We had a simple shell script + maven profile to copy the right environment file into place before creating a .war file. (Note: It would have been nice to use maven alone without the shell script, but we ran into some problems moving files around with maven).

Object-based configuration

Did you notice that I slipped in a value-ref="proxy1"? Using a Spring XML file anabled me to create environment specific beans rather than a collection environment specific String properties. That higher level configuration capability gave the flexibility to think of configuration in terms of objects rather than in terms of Strings. Grails gives that capability out of the box, and I built a Grails system last yea... object-based configuration simply feels more natural to me at this point.

Configuration simplification

Spring EL had another great benefit. You can build simple POJOs through SpEL which allow you to bypass icky XML. For example, that value-ref="proxy1" that I showed above had 13 lines of XML code without EL, compared with 4 lines of XML with EL.

Here's what building a java.net Proxy looked like pre-EL:

  <bean id="myProxy" class="java.net.Proxy">
    <constructor-arg>
      <bean class="java.net.Proxy$Type" factory-method="valueOf">
         <constructor-arg value="HTTP" />
      </bean>
    </construcor-arg>
    <constructor-arg>
      <bean class="java.net.InetSocketAddress">
         <constructor-arg value="proxy.mycompany.com" />
         <constructor-arg value="1234" />
       </bean>
    </constructor-arg>
  </bean>

That icky XML was one reason why so many folks simply hated Spring. I didn't like it either, but I lived with it until now. There are some EL tricks that allowed the following "simpler" configuration:

  <bean id="myProxy" class="java.net.Proxy">
    <constructor-arg value="#{T(java.net.Proxy$Type).HTTP} />
    <constructor-arg value="#{new java.net.InetSocketAddress('proxy.mycompany.com', 1234)}" />
  </bean>

That's still not as short as plain old java code (or a groovy script), but it's a lot better than the original XML. The syntax takes a bit of getting used to, but it allows me to have a clearer picture of how my application is configured by:

  1. providing a more concise picture of what this specific bean does
  2. allowing me to see more of my configuration on a single page, so that I can get a quicker holistic view of my application's configuration.

Conclusion

I'm really happy with the incremental steps that Spring has taken over the years at improving configuration. I hope that these little tips helped. If you have more EL or configuration niceties, please let me know!

From http://www.jroller.com/Solomon/entry/spring_el_environmental_configuration_and

Published at DZone with permission of Solomon Duskis, author and DZone MVB.

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

Tags:

Comments

Peter Veentjer replied on Wed, 2010/03/31 - 2:17am

I would solve the 'ugly' syntax problem by using a different language for that part (scala, ruby, groovy etc) by creating an internal DSL. This internal DSL (a DSL that can lift on the features of the host language) could provide a lot cleaner and more powerful syntax. There already are a few Spring extensions that use this approach.

Personally I'm 'happy' to see large chunks of XML. Definitely better than all those annotations that prevent reuese and make  systems hard to understand because there is no central 'drawing' of the system anymore.

 

Peter Veentjer

Multiverse: Software Transactional Memory for Java

http://multiverse.codehaus.org

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.