B.3. Coding a NamespaceHandler

Spring Framework

B.3. Coding a NamespaceHandler

In addition to the schema, we need a NamespaceHandler that will parse all elements of this specific namespace Spring encounters while parsing configuration files. The NamespaceHandler should in our case take care of the parsing of the myns:dateformat element.

The NamespaceHandler interface is pretty simple in that it only features three methods:

  • init() - allows for initialization of the NamespaceHandler and will be called by Spring before the handler is used

  • BeanDefinition parse(Element element, ParserContext parserContext) - called when Spring encounters a top-level element (not nested inside a bean definition or a different namespace). This method can register bean definitions itself and/or return a bean definition.

  • BeanDefinitionHolder decorate(Node element, BeanDefinitionHolder definition, ParserContext parserContext) - called when Spring encounters an attribute or nested element of a different namespace, inside for example the Spring namespace. The decoration of one or more bean definitions is used for example with the out-of-the-box scopes Spring 2.0 comes with (see 第 3.4 节 “bean的作用域” for more information about scopes). We'll start by highlighting a simple example, without using decoration, after which we will show decoration in a somewhat more advanced example.

Although it is perfectly possible to code your own NamespaceHandler for the entire namespace (and hence provide code that parses each and every element in the namespace), it is often the case that each top-level XML element in a Spring XML configuration file results in a single bean definition (as in our case, where the myns:dateformat element results in a SimpleDateFormat bean definition). Spring features a couple of convenience classes that support this scenario. In this example, we'll use the most often used convenience class which is the NamespaceHandlerSupport class:

package org.springframework.samples.xml;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class MyNamespaceHandler extends NamespaceHandlerSupport {
    
    public void init() {
        registerBeanDefinitionParser("dateformat", 
                new SimpleDateFormatBeanDefinitionParser());        
    }
}