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
;
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
;
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
='广东省深圳市'}