The spring framework, starting with version 2.0, provides a schema-style spring XML format to define the bean extension mechanism. The introduction of schema-based XML is intended to simplify the XML configuration form of traditional. By the definition of schema, some configuration forms that need to be defined by a couple of bean definitions or complex bean combinations are presented in a simple and readable configuration.
schema-based XML consists of three parts, and we are illustrated by a picture:
namespace
--With a clear logical classification
element
--Have a very clear process semantics
attributes
--With very simple configuration options
For example, the <mvc:annotation-driven />
meaning of this configuration is to implement annotation-driven configuration within the MVC space. Among them, MVC represents the effective range of configuration, Annotation-driven expresses a dynamic process, the actual logical meaning is: The entire SPRINGMVC implementation is based on annotation mode, please register the relevant behavior mode for me.
The following explains how to write custom XML for the bean definition parsing and integration of this parsing into the spring IOC container. In the following sections we will mention an important concept that is bean definition. In fact, there is an important concept in spring that is the bean. And Beandefinition This object is the corresponding tag parsed object.
Use the following simple steps to create a new XML configuration extension:
- Authoring
An XML schema to describe your custom element (s)
- Coding
A custom NamespaceHandler
implementation (this is a very simple step, don ' t worry)
- Coding
One or more BeanDefinitionParse
implementations (this is the most important)
- Registeringr
register the above to spring (this is also a simple step)
The steps above will be described in turn. For example, we need to create an XML extension (custom XML element) that allows us to configure the object in a simple way SimpleDateFormat
(in a java.text
package). Finally we can define a SimpleDateFormat
type of bean definition as follows:
<myns:dateformat id= "DateFormat" pattern= "Yyyy-mm-dd hh:mm" lenient= "true"/>
1. Authoring the schema
To create an XML configuration extension for a spring IOC container, we need to write an XML schema to describe the extension. The following schema we can use to configure the SimpleDateFormat
object
<!--myns.xsd (inside package org/springframework/samples/xml)--><?xml version= "1.0" encoding= "UTF-8"?> <xsd:schema xmlns= "Http://www.mycompany.com/schema/myns" xmlns:xsd= "Http://www.w3.org/2001/XMLSchema" xml ns:beans= "Http://www.springframework.org/schema/beans" targetnamespace= "Http://www.mycompany.com/schema/myns" elementformdefault= "qualified" attributeformdefault= "unqualified" > <xsd:import namespace= "Http://www.spr Ingframework.org/schema/beans "/> <xsd:element name=" DateFormat "> <xsd:complexType> < ;xsd:complexcontent> <xsd:extension base= "Beans:identifiedtype" > <xsd:attrib Ute Name= "lenient" type= "Xsd:boolean"/> <xsd:attribute name= "pattern" type= "xsd:string" use= "requ Ired "/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element></xsd:Schema>
The schema above will be used to configure the SimpleDateFormat
object. Use element directly in an XML application context file <myns:dateformat />
.
<myns:dateformat id= "DateFormat" pattern= "Yyyy-mm-dd hh:mm" lenient= "true"/>
Note: The XML fragment above is essentially the same as the following XML fragment.
<bean id= "DateFormat" class= "Java.text.SimpleDateFormat" > <constructor-arg value= "Yyyy-hh-dd hh:mm"/ > <property name= "lenient" value= "true"/></bean>
2, Coding a Namespacehandler
For the schema above, we need one NamespaceHandler
to parse all the elements in this particular namespace configuration file that spring encounters. This will be concerned with NamespaceHandler
parsing myns:dateformat
elements.
This NamespaceHandler
interface is relatively simple, and it includes three important methods.
init()
The. will be instantiated before spring uses handlerNamespaceHandler
BeanDefinition parse(Element, ParseContext)
-When spring encounters the top-level element defined above (i.e., myms) it will be called, this method can register the bean definitions and can return a bean definition.
BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)
will be called when Spring encounters a attribute or an element embedded in namespace.
In many cases, each top-level XML element in the spring XML configuration file represents a single type of bean definition (in our case, a single <myns:dateformat>
The element represents a single SimpleDateFormat bean definition). Spring provides a number of convenient classes to support this scenario. In this example, we will use the NamespaceHandlerSupport
.
Package Org.springframework.samples.xml;import Org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class Mynamespacehandler extends Namespacehandlersupport {public void init () { Registerbeandefinitionparser ("DateFormat", New Simpledateformatbeandefinitionparser ());} }
3, Beandefinitionparser
BeanDefinitionParser
The responsibility is to parse the XML element that defines the schema in top-level. During parsing, we have to access XML elements, so we can parse our custom XML content, such as the following example:
Package Org.springframework.samples.xml;import Org.springframework.beans.factory.support.BeanDefinitionBuilder; Import Org.springframework.beans.factory.xml.abstractsinglebeandefinitionparser;import Org.springframework.util.stringutils;import Org.w3c.dom.element;import Java.text.simpledateformat;public Class Simpledateformatbeandefinitionparser extends Abstractsinglebeandefinitionparser {1 protected Class Getbeanclass ( Element Element) {return simpledateformat.class; 2} protected void Doparse (element element, beandefinitionb Uilder Bean) {//This would never is null since the schema explicitly requires that a value being supplied stri ng pattern = Element.getattribute ("pattern"); Bean.addconstructorarg (pattern); This however is a optional property String lenient = Element.getattribute ("lenient"); if (Stringutils.hastext (lenient)) {Bean.addpropertyvalue ("lenient", boolean.valueof (lenient)); } }}
Attention:
- We use spring
AbstractSingleBeanDefinitionParser
to deal with some basic work of creating a single beandefinition.
- We rewrote the
AbstractSingleBeanDefinitionParser
Doparse method of the parent class to implement our own logic of creating a single type of beandefinition.
4. Registering the handler and the schema
The coding is done. The following is the thing that the logic in spring XML parsing can weave into our defined element; We need to register our custom namespacehandler and custom XSD files in two specific target properties files. These properties files need to be placed under the ' Meta-inf ' application in your project.
1) meta-inf/spring.handlers
This properties file is called a ‘spring.handlers‘
map that contains XML Schema URIs and namespace processing classes. In our example, we need to look like the following:
http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler
The first part of a key-value pair (key) is the URI that associates your custom namespace extension and needs to match the attributes in your custom XSD schema ‘targetNamespace‘
.
2) Meta-inf/spring.schemas
This properties file is called ‘spring.schemas‘
, containing the location of the XML Schema in Classpath. This file is primarily to prevent spring from loading this schema file on the network. If you specify this properties file mapping, Spring will look for this schema in classpath (in this case under ‘org.springframework.samples.xml‘
the package ‘myns.xsd‘
)
http\://www.mycompany.com/schema/myns/myns.xsd=org/springframework/samples/xml/myns.xsd
You'd better deploy your XSD file in your NamespaceHandler
and BeanDefinition
class classpath.
5. Final effect Demonstration
If you have completed the above steps, you have successfully defined your own BeanDefinition
in the spring IOC container. We can obtain and use this Bean object from the spring IOC container.
1) configuration file
Schema-beans.xml
<?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:myns= "Http://www.mycompany.com/schema/myns" xsi:schemalocation= "Http://www.springframework.org/schema/beans Http://www.springframework.org/schema /beans/spring-beans.xsd Http://www.mycompany.com/schema/myns http://www.mycompany.com/schema/myns/myns.xsd " > <myns:dateformat id= "DateFormat" pattern= "Yyyy-mm-dd hh:mm" lenient= "true"/></beans >
2) Test class
Schemabeandefinitiontest.java
Package Org.springframework.samples.xml;import Org.springframework.context.applicationcontext;import Org.springframework.context.support.classpathxmlapplicationcontext;import Java.text.simpledateformat;public Class Schemabeandefinitiontest {public static void Main (string[] args) { ApplicationContext context = new CLASSP Athxmlapplicationcontext ("Schema-beans.xml"); SimpleDateFormat DateFormat = Context.getbean ("DateFormat", simpledateformat.class); SYSTEM.OUT.PRINTLN ("-------------------Gain Object--------------------"); System.out.println (DateFormat); }}
3) Project structure:
Note: The idea static resource must be placed under the resources, otherwise it will be an error.
4) Operation Result:
Spring Extensible XML