问题Dubbo如果扩展Spring Schema?
从一个例子开始,写一个类让Spring解析 对比Dubbo
- DubboNamespaceHandler extends NamespaceHandlerSupport
- MyNamespaceHandler extends NamespaceHandlerSupport
```Java
public class MyNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("people",new PeopleBeanDefinitionParser());
}
}
```
- 这里需要一个解析器 new PeopleBeanDefinitionParser()
- registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
```Java
public class PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class getBeanClass(Element element) {
return People.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String name = element.getAttribute("name");
String age = element.getAttribute("age");
String id = element.getAttribute("id");
if (StringUtils.isNotBlank(name)){
builder.addPropertyValue("name",name);
}
if (StringUtils.isNotBlank(age)){
builder.addPropertyValue("age",age);
}
if (StringUtils.isNotBlank(id)){
builder.addPropertyValue("id",id);
}
}
}
```
- 从下图的分析中我们还了解到 我们还需要一个xsd配置和一个handlers还有一个schemas
- 模仿着搞出来
- 1.xsd 用于配置解析的元素

- 2.handlers 用于指定解析元素的类对应上面写的MyNamespaceHandler it.caoxin/schema/peop…
- 3.schemas 用于指定解析元素的xsd文件 it.caoxin/schema/peop…

- 4.标准类用于接收解析出来的xml
```Java
public class People {
private String id;
private String name;
private Integer age;
// 省略getter setter
}
```
- 5.执行如下代码
```Java
// 获取配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取配置文件中自定义schema的bean
//
// 定义了这个schema后我们需要找到对应的验证文件 和 bean解析类
// http://it.caoxin/schema/people bean解析实体类
// http://it.caoxin/schema/people.xsd 提供需要验证的文件
People p= (People) ctx.getBean("cutesource");
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
```
-
6.程序运行结果
-
cutesource
-
caoxinxin
-
15
-
Spring在哪里解析这个类的?调用链
-
org.springframework.context.support.AbstractApplicationContext#refresh()
-
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
-
org.springframework.context.support.AbstractApplicationContext#refreshBeanFactory
-
org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
-
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions
-
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
-
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
-
这里的做法是通过元素获取NamespaceURI,再通过取NamespaceURI获取对应的NameSpaceHandler,最后调用NameSpaceHandler.parse()进行解析,返回BeanDefinition

-
思想:
-
通过spring.handler配置自定义元素解析器。
-
通过spring.schemas对需要解析的内容进行定义。
-
高扩展性,解耦的体现。