Spring的强大之处不仅仅在于它为Java开发者提供了极大便利,更在于它的开放式架构,使得用户可以拥有最大扩展Spring的能力。
我们在用xml定义spring信息时,默认的element只包含beans,bean,import,alias这四个,其它任何标签都属于自定义标签,均需要引入相应的命名空间,如:context,aop标签等。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//处理默认的标签元素
parseDefaultElement(ele, delegate);
}
else {
//处理自定义的标签元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
对应的源码处理在DefaultBeanDefinitionDocumentReader类的parseBeanDefinitions方法里面。
自定义标签元素
1,定义People.java
public class People {
private String id;
private int age;
private String name;
private String address;
public People(String id, int age, String name, String address) {
this.id = id;
this.age = age;
this.name = name;
this.address = address;
}
public People() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "People{" +
"id='" + id + '\'' +
", age=" + age +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
2,在resources/META-INF目录下定义people.xsd,spring.handlers,spring.schemas文件
people.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.bobo.com/schema/people"
xmlns:tns="http://www.bobo.com/schema/people"
elementFormDefault="qualified">
<element name="people">
<complexType>
<attribute name ="id" type = "string"/>
<attribute name ="age" type = "int"/>
<attribute name ="name" type = "string"/>
<attribute name ="address" type = "string"/>
</complexType>
</element>
</schema>
spring.handlers
http\://www.bobo.com/schema/people=com.bobo.custom.PeopleNamespaceHandler
spring.schemas
http\://www.bobo.com/schema/people.xsd=META-INF/people.xsd
3,创建对应的namespaceHandler类PeopleNamespaceHandler.java
package com.bobo.custom;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* @author bobo
* @date 2020-10-20
*/
public class PeopleNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
super.registerBeanDefinitionParser("people",new PeopleBeanDefinitionParser());
}
}
4,创建对应的BeanDefinitionParser类PeopleBeanDefinitionParser.java
package com.bobo.custom;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author bobo
* @date 2020-10-20
*/
public class PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return People.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String id = element.getAttribute("id");
String age = element.getAttribute("age");
String name = element.getAttribute("name");
String address = element.getAttribute("address");
if (StringUtils.hasLength(id)){
builder.addPropertyValue("id",id);
}
if (StringUtils.hasLength(age)){
builder.addPropertyValue("age",age);
}
if (StringUtils.hasLength(name)){
builder.addPropertyValue("name",name);
}
if (StringUtils.hasLength(address)){
builder.addPropertyValue("address",address);
}
}
}
5,创建application-context.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:bo="http://www.bobo.com/schema/people"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.bobo.com/schema/people http://www.bobo.com/schema/people.xsd">
<bo:people id="bo" age="20" name="bobo" address="广东省深圳市"></bo:people>
</beans>
6,创建测试类
package com.bobo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
System.out.println(context.getBean("bo"));
}
}
运行输出
People{
id='bo', age=20, name='bobo', address='广东省深圳市'}