preface
In the current Java ecosystem, Spring is the most core framework. All development components, such as Mybatis and Dubbo, which are well known to us, should be integrated with Spring if they want to be used in a wide range and more conveniently, as well as all kinds of internal packaged components, including Redis, MQ and configuration center.
With the integration step, we only need to introduce the corresponding JAR, such as Mybatis -Spring, and then use the function of Mybatis in the Spring project after simple configuration. It is precisely because of this convenience that we do not carry out in-depth research in many cases.
Integration refers to extending the Spring framework so that it works seamlessly with Spring projects. Spring designed a good extension mechanism, this article will be a simple introduction to Spring extension methods and principles.
XML Schema extension
Open the source code for Mybatis and Dubbo and you will find two files in the meta-INF directory, Spring.Handlers and Spring.Schemas, which are the key entry points for the XML Schema extension.
XSD
XSD, XML Schema Definition, XML Definition.
XML Schema defines the structure of XML documents. The XML Schema language is also called XML Definitions, or XSD.
XSD syntax and use more simple, can refer to www.w3school.com.cn/schema/inde…
In simple terms, XSD is used to specification XML files, including elements (simple elements, complex elements), attributes, and attribute types and constraints in XML.
Spring XML Schema extension of the first step is to define an XSD file, such as Spring – beans for the XSD file for www.springframework.org/schema/bean…
To provide a brief introduction to the Spring XML Schema extension implementation, here is a simple example that emulates a simple DistributedId generator without implementing the specific functionality. XSD is defined as follows (file name distributedid.xsd, in the meta-inf directory) :
<xsd:schema xmlns="http://www.hexup.com/schema/distributed-id"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.hexup.com/schema/distributed-id">
<xsd:element name="distributed-id">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"></xsd:attribute>
<xsd:attribute name="bizCode" type="xsd:string"></xsd:attribute>
<xsd:attribute name="length" type="xsd:int"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Copy the code
The above XSD file defines a complex element, the distributed id, bizCode, length, which looks like:
<distributed-id id="xxx" bizCode="xxx" length="xxx"></distributed-id>
Copy the code
Note: XMLNS stands for XML namespace, and the HTTP link address following it may not exist because the XSD will be placed in the meta-INF of the current project.
Configure spring. Handlers and spring. Schemas
The spring.schemas file is used to illustrate the file paths for XSD, as shown in the following two diagrams. The Spring.schemas file is used to illustrate the processing classes that parse the tags defined by such XSD. The processing classes are described in detail below.
NameSpaceHandler and BeanDefinitionParser
Define the class NamespaceHandlerSupport DistributedIdNamespaceHandler inheritance, the init method for registering BeanDefinition parser, namely to parse the XML in the corresponding labels for Spring beans.
public class DistributedIdNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init(a) {
registerBeanDefinitionParser("distributed-id".newDistributedIdParser()); }}Copy the code
BeanDefinitionParser is also created
public class DistributedIdParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
// Parse tags in XML
String bizCode = element.getAttribute("bizCode");
int length = Integer.valueOf(element.getAttribute("length"));
String id = element.getAttribute("id");
// Create the DistributedIdFactoryBean bean
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.getRawBeanDefinition().setBeanClass(DistributedIdFactoryBean.class);
builder.setScope(BeanDefinition.SCOPE_SINGLETON);
builder.addPropertyValue("bizCode", bizCode);
builder.addPropertyValue("length", length);
BeanDefinition beanDefinition = builder.getBeanDefinition();
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
returnbeanDefinition; }}Copy the code
DistributedIdFactoryBean implements the FactoryBean interface to create the DistributedIdComponent Bean, as follows
public class DistributedIdFactoryBean implements InitializingBean.FactoryBean<DistributedIdComponent> {
private String bizCode;
private int length;
private DistributedIdComponent distributedIdComponent;
@Override
public DistributedIdComponent getObject(a) throws Exception {
return distributedIdComponent;
}
@Override
publicClass<? > getObjectType() {return DistributedIdComponent.class;
}
@Override
public boolean isSingleton(a) {
return false;
}
@Override
public void afterPropertiesSet(a) throws Exception {
distributedIdComponent = new DistributedIdComponent(bizCode, length);
}
public void setBizCode(String bizCode) {
this.bizCode = bizCode;
}
public void setLength(int length) {
this.length = length; }}Copy the code
The target Bean DistributedIdComponent looks like this:
public class DistributedIdComponent {
private String bizCode;
private int length;
public DistributedIdComponent(a) {}public DistributedIdComponent(String bizCode, int length) {
this.bizCode = bizCode;
this.length = length;
}
public String generateId(a) {
System.out.println("mock generate id");
return String.valueOf(System.currentTimeMillis()).substring(0, length);
}
public String getBizCode(a) {
return bizCode;
}
public void setBizCode(String bizCode) {
this.bizCode = bizCode;
}
public int getLength(a) {
return length;
}
public void setLength(int length) {
this.length = length; }}Copy the code
use
The spring configuration file, spring-service. XML, configures the distributed-id tag and the corresponding attribute values as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:distributed-id="http://www.hexup.com/schema/distributed-id"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.hexup.com/schema/distributed-id http://www.hexup.com/schema/distributed-id.xsd">
<distributed-id:distributed-id id="test" bizCode="test" length="8"></distributed-id:distributed-id>
</beans>
Copy the code
Run container validation:
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-service.xml");
DistributedIdComponent bean = context.getBean(DistributedIdComponent.class);
String id = bean.generateId();
System.out.println("id:"+ id); }}Copy the code
conclusion
This article mainly introduces the use of Spring XML Schema extension mechanism. The general steps are to define XSD files, configure spring.Schemas, code implementation classes for NameSpaceHanlder and BeanDefinitionParser, and configure Spring.Handlers. There will be a follow-up article detailing how the Spring source code implements extensions and why factoryBeans are used to create specific beans.