Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Custom components with Spring 2.5

A hands-on introduction to Spring's flexible component model

  • Print
  • Feedback

Page 2 of 5

Define a component using custom namespaces

The first step is to create an XSD file that defines the namespace and attributes for your component. The component to be defined will occupy a new namespace, http://www.jeffhanson.com/schema/service/foobar, and have one property: message.

The new component is defined in the XSD file shown in Listing 1.

Listing 1. The component definition in an XSD file

<xsd:schema xmlns="http://www.jeffhanson.com/schema/service/foobar"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  targetNamespace="http://www.jeffhanson.com/schema/service/foobar"
                 elementFormDefault="qualified"
                 attributeFormDefault="unqualified">
  <xsd:element name="component">
    <xsd:complexType>
      <xsd:attribute name="id" type="xsd:ID" use="required"/>
      <xsd:attribute name="message" type="xsd:string"/>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

The definition in Listing 1 specifies two attributes for an element named component. Once packaged and deployed to the Spring classpath, this definition will be parsed and consumed by the Spring framework.

Encapsulate component logic in a Spring bean

Once you have defined the component in your XSD file the next step is to write the logic for the component, encapsulated in a simple Java bean. The Spring bean in Listing 2 exposes one property, message, along with a sayHello method that prints the message property to System.out.

Listing 2. The component logic encapsulated in a Java bean

package com.jeffhanson.spring.beans;

public class Foobar
  implements IHelloWorld
{
  private String message = "Hello World!";
  
  public void setMessage(String message)
  {
    this.message = message;
  }

  public String getMessage()
  {
    return message;
  }
  
  public void sayHello()
  {
    System.out.println(message);
  }
}

The value of the message property will be specified by the Spring deployment container, using Spring's application context configuration file.

Implement a custom namespace handler

For Spring to be able to consume the schema definition of the component, you must provide a NamespaceHandler to the Spring container. The handler, an implementation of the org.springframework.beans.factory.xml.NamespaceHandler interface, is responsible for parsing the elements of a component namespace.

The NamespaceHandler interface defines three methods:

  • init() is invoked by the Spring container after construction of the component but before any custom elements are parsed.
  • parse() is invoked by the Spring container to parse a given Element and register any resulting BeanDefinitions with Spring's bean-definition registry for a given parser context.
  • decorate() is invoked by the Spring container to parse a specified node and decorate/augment the supplied BeanDefinitionHolder object, returning the decorated definition.

Spring provides a number of convenience classes that handle much of the default processing for a simple component definition. One of these, the NamespaceHandlerSupport class, will be used by the simple component namespace handler shown in Listing 3.

Listing 3. A spring custom namespace handler

package com.jeffhanson.spring.beans;

import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.w3c.dom.Element;

public class FoobarNamespaceHandler extends NamespaceHandlerSupport
{
  public FoobarNamespaceHandler()
  {
    registerBeanDefinitionParser("component", new FoobarBeanDefinitionParser());
  }

  public void init()
  {
  }

  private static class FoobarBeanDefinitionParser
    extends AbstractSimpleBeanDefinitionParser
  {
    protected Class getBeanClass(Element element)
    {
      return Foobar.class;
    }
  }
}

Notice that the namespace handler implementation in Listing 3 encapsulates an inner class that is presented to the Spring container as the parser for the component element.

  • Print
  • Feedback

Resources