XML Syntax Sugar in Spring 2.0

Rod Johnson

If you've followed October's Spring 2.0 release, you will know that one of the big new features was XML extension name spaces: the ability to define new XML elements and attributes that generate Spring metadata, and can be used alongside regular bean definitions. This provides a valuable new extension point and makes Spring configuration both more simpler to use for many repeated tasks and more powerful.

However, there is also a sweet little piece of syntax sugar that you may not have noticed–probably because no one in the Spring team has gotten around to telling you… Having promised myself for a while that I was going to do a code-centered blog next, here goes.

The move to XML schema to allow extension namespaces also allows a little shortcut, using attributes instead of subelements for property values. These attributes are not validated, but because we are using XML schema, rather than a DTD, we can still retain all other validation. As the attribute names are property names, XML validation wouldn't add anything anyway; this is a problem of Java-based validation, rather than XML structure.
Imagine the following Java object, with two simple properties and a dependency on an associated object:

public class Person {
       
   private int age;
       
   private String name;
       
   private House house;

   public void setAge(int age) {
      this.age = age;
   }

   public void setName(String name) {
      this.name = name;
   }
       
   public void setHouse(House house) {
      this.house = house;
   }
}

This can be configured in Spring 2.0 using XML as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean class="com.interface21.spring2.ioc.Person"
   p:name="Tony"
   p:age="53"
   p:house-ref="number10"
/>

       
<bean class="com.interface21.spring2.ioc.House"
   id="number10"
   p:name="10 Downing Street"
/>

       
</beans>

Note how the properties can be supplied using attributes, rather than elements. This works through the magic of the special namespace: "p". This is a special namespace that is not validated, but intended to allow the use of attributes with names matching Java property names.

With simple types we simply use the property name in the "p" namespace, as in "p:name". When injecting references to other Spring beans, use the "-ref" suffix, as in "p:house-ref".

This shortcut syntax is particularly compelling when you want to use autowiring. For example, consider the following variant:

<bean class="com.interface21.spring2.ioc.Person"
   autowire="byType"
   p:name="Tony"
   p:age="53"
/>

Here we have not set the "house" property, as autowiring can take care of that. You could even use default-autowire at the <beans> element level to have autowiring across the entire file.

The following snippet from Spring 1.0 or 1.1 usage illustrates how much Spring configuration has reduced the minimum number of angle brackets in the last two major releases (1.2 and 2.0):

<bean class="com.interface21.spring2.ioc.Person">
   <property name="name"><value>"Tony"</value></property>
   <property name="age"><value>"53"</value></property>   
   <property name="house"><ref local=â€?number10â€? /></property>
</bean>

In Spring 1.2 we introduced the "value" and "ref" attributes, instead of requiring subelements of <property> in most cases, while in Spring 2.0 it’s now possible to use attributes pure and simple.

Of course, the traditional syntax continues to work–Spring 2.0 just adds additional options. Use the traditional longhand form when the property value is complex and not legal or readable as an attribute value. And, of course, there is no need to rewrite existing configuration files, as Spring 2.0 is entirely backward compatible overall.

The new syntax is particularly nice when putting configuration samples into presentations. Which reminds me that my real job for today is finishing my slides for the Spring Experience… Hope to see you there!

 

15 responses


  1. This looks good!

    There's a small typo, 3rd to last para: "…while in Spring 1.2 it’s possible to use attributes…" s/b "…while in Spring 2.0 it’s possible to use attributes…"


  2. Thanks Russell–I'll fix it.


  3. The schemalocation changed in 2.0 final, should be http://www.springframework.org/schema/beans/spring-beans-2.0.xsd


  4. Nice shorthand for property setting.

    One small point: -

    p:house-ref="number10"

    Adding "-ref" suffix to the attribute name does not feel clean. I would have preferred: -

    p-ref:house="number10"

    Although this does require the use of an extra namespace.


  5. Just a short note: Spring IDE 2.0 will provide support for the new shortcut syntax. A preview is available at http://springide.org/project/wiki/SpringsPNamespace.

    Christian


  6. I defently agree with Matt - another namespace would be cleaner and feels more natural.

    Timmo


  7. Although concise, I think the syntax is still a little bit confusing. I like the idea of XBean's custom XML much better. (Plug: I posted about that here)

    -Stefan


  8. Interesting. Does the p-namespace support (and how) Lists or Maps?


  9. ut p namespace for a while, but I've come across a problem using it within a nested bean.

    For example, this works:

    But the following one doesn't:

    Do you know what I'm doing wrong?

    Thanks in advance.


  10. There's no doubt that the new syntax is considerably more concise and more convenient. The -ref suffix does come across as a little inconsistent but hey I'll leave that to those who know best. I have two questions regarding the above though.

    Will this new syntax or does it already have editor autocompletion support in Eclipse? It didn't seem to have this when I tried just now.
    Is there an equivalent in the new syntax of <ref local=""> from the old syntax?

    Many thanks.


  11. I'm having the same problem as Mikel above. Using the p: namespace in a nested bean, mising and matching with "regular" tags, or using the p: notation within a Bean that is an entry in a or doesn't work. The Bean is instantiated correctly, but none of the properties specified using the p: notation are ever populated (accessors are never called). Is this a bug? A feature? Is the p: notation documented anywhere other than here?


  12. mising and matching with "regular" tags

    Sorry, that should read:

    mixing and matching with "regular" <property> tags


  13. I'm having the same problem as Mikel above. Using the p: namespace in a nested bean, mising and matching with "regular" tags, or using the p: notation within a Bean that is an entry in a or doesn't work.

    It looks like this was fixed in 2.0.2:

    http://opensource.atlassian.com/projects/spring/browse/SPR-2955

    It didn't work for me in 2.0 but does in 2.0.2.


  14. I tried the p namespace within a list and it did not work
    for example

    When this example run the attributes contain list on one NULL element. The inner
    class didn't get created.

    Can you please let me know what I am doing worong
    Thanks


  15. I tried the p namespace within a list and it did not work.

    For example

    <bean id="class1" class="someClass">
    <p:attributes>
    <list>
    <bean class="anotherclass" p.name="test1" p.id="id1"/>
    </list>
    </p:attributes>
    <bean>

    When I run above example the attributes contain list on one NULL element. The inner class didn't get created.

    Can you please let me know what I am doing wrong
    Thanks

7 trackbacks

Leave a Reply

Quote selected text