As you can see, the namespace handler shown above registers so-called BeanDefinitionParsers
.
A BeanDefinitionParser
in this case will be consulted if the namespace handler
encounters an XML element of the type that has been mapped to this specific bean definition parser (which
is dateformat
in this case).
In other words, the BeanDefinitionParser
is responsible for parsing
one distinct top-level XML element defined in the schema.
In the parser, we'll have access to the XML element (and its subelements)
and the ParserContext
. The latter can be used to obtain a reference
to the BeanDefinitionRegistry
, for instance, as seen in the
example below.
package org.springframework.samples.xml;
import java.text.SimpleDateFormat;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
public class SimpleDateFormatBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
// create a RootBeanDefinition that will serve as configuration
// holder for the 'pattern' attribute and the 'lenient' attribute
RootBeanDefinition beanDef = new RootBeanDefinition();
beanDef.setBeanClass(SimpleDateFormat.class);
// never null
since the schema requires it
String pattern = element.getAttribute("pattern");
beanDef.getConstructorArgumentValues().addGenericArgumentValue(pattern);
String lenientString = element.getAttribute("lenient");
if (StringUtils.hasText(lenientString)) {
// won't throw exception if validation is turned on (boolean type set in schema)
beanDef.getPropertyValues().addPropertyValue("lenient", new Boolean(lenientString));
}
// retrieve the ID attribute that will serve as the bean identifier in the context
String id = element.getAttribute("id");
// create a bean definition holder to be able to register the
// bean definition with the bean definition registry
// (obtained through the ParserContext)
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDef, id);
// register the BeanDefinitionHolder (which contains the bean definition)
// with the BeanDefinitionRegistry
BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry());
return beanDef;
}
}
BeanDefinition
and registering it
with the BeanDefinitionRegistry
. Note that you don't necessarily have to
register a bean definition with the registry or return a bean definition
from the parse()
method. You are free to do whatever you
want with the information given to you (i.e. the XML element) and the
ParserContext
.
The ParserContext
provides access to following properties:
readerContext
- provides access
to the bean factory and also to the NamespaceHandlerResolver
, which
can optionally be used to resolve nested namespaces.
parserDelegate
- controlling component
that drives the parsing of (parts of) the configuration file. Typically
you don't need to access this.
registry
- the BeanDefinitionRegistry
that allows you to register newly created BeanDefinition
instances with.
nested
- indicates whether or the XML element that is currently
being processed is part of a outer bean definition (in other words, it's defined similar
to traditional inner-beans).