webx3.0-SpringExt

NameSpace初探

和C++,C#等高级语言一样,XML同样面临大量文件放在一起的时候变量重名的问题,所以要用namespace把名字相同意义不同的变量隔离开。以下是一个简单的XML文档:

<root>
   <child id = ‘0’>
      hello world
   </child>
   <child id='1'>
     one
   </child>
</root>

这个例子里面没有namespace,下面是一段豆瓣API返回的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="<a href="http://www.w3.org/2005/Atom" xmlns:db="<a href="http://www.douban.com/xmlns/" xmlns:gd="<a href="http://schemas.google.com/g/2005" xmlns:opensearch="<a href="http://a9.com/-/spec/opensearchrss/1.0/" >
  <id>http://api.douban.com/event/10069638</id>
  <title>Debugging the Web </title>
  <category scheme="<a href="http://www.douban.com/2007#kind" term="<a href="http://www.douban.com/2007#event.salon"/>
  <author>
    <link href="<a href="http://api.douban.com/people/1057620" />
    <link href="<a href="http://www.douban.com/people/aka/"/>
    <link href="<a href="http://t.douban.com/icon/u1057620-16.jpg"/>
    name>胖胖的大头鱼</name>
    <uri>http://api.douban.com/people/1057620</uri>
</author>
<db:attribute name="invite_only">no</db:attribute>

1、这里<entry xmlns="http://www.w3.org/2005/Atom" ,xmlns就是xml namespace的意思。

2、xmlns:db="http://www.douban.com/xmlns/" ,结合<db:attribute name="invite_only">no</db:attribute>这句话,可以理解了,db是一个namespace的简称,方便写在元素的名字前面,这样<db:attribute> 和 <attribute>, <gd:attribute>就不一样了。这种简称可以在一个文档里面区别变量,但是对大量的文档还是不行,所以namespace还有一个全称,就是这里的http://www.douban.com/xmlns/。这个全称其实写什么内容都行,对XML Parser来说都是当做字符串来处理的,但一来想名字比较麻烦,二来可以顺道做个广告,所以大家一般都用的网址。Parse的时候Parser根据全称来区别变量,所以就算两个文档中都有<db:attribute>,只要全称不一样,都没有问题。

3、但那个http://www.w3.org/2005/Atom到底是个啥啊,连个简称都没有。他的简称就是””,空串。这东西被称为default namespace,那些看上去没有前缀的都是在这个namespace下的。所以那个<author>不是裸的啊,人家其实是 <”http://www.w3.org/2005/Atom” : author> 所以裸的程序当然是解析不了的了。

为何要引入SpringExt

详见:http://www.openwebx.org/docs/springext.html

赋予了scheme组件化的功能,既能主拓展,又可以被拓展

SpringExt原理

运用了XML Schema中的<xsd:any>定义,<xsd:any>定义只关心namespace,不关心element的名称,自然可以接受未知的 element,前提是namespace必须一致。看下面例子:

<xsd:element name="resource" type="ResourceLoadingServiceResourceType">
<xsd:complexType name="ResourceLoadingServiceResourceType">
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:any namespace="<a href="http://www.alibaba.com/schema/services/resource-loading/loaders" />
    </xsd:choice>
    <xsd:attribute name="pattern" type="xsd:string" use="required" />
</xsd:complexType>

定义了schema的拓展,但是spring还是无法解析,这时候需要提供对应的parses:

test=com.alibaba.parseTest

最后spring是如何把这一系列的规则组织起来的呢?

SpringExt如何使用

拓展点

1、定义:Webx3框架中,允许使用者对命名空间进行拓展,这些可以拓展的空间叫做拓展点,在使用拓展功能前需要首先需要配置拓展点

2、配置文件位置:位于classpath的META-INF的spring-configuration-points文件中:

services=http://www.alibaba.com/schema/services; defaultElement=service
 
services/data-resolver/factories=http://www.alibaba.com/schema/services/data-resolver/factories; defaultElement=factory; nsPrefix=dr-factories

其中包含了拓展点名称、命名空间URL、默认元素和命名空间前缀

捐献

1、定义:有了拓展点,就可以在该拓展点上进行拓展了,我们称为捐献

2、组成成分:包含一份XSD文件和一个NameSpace的解析类

3、配置文件位置:

XSD文件定义在classpath的"{configurationName}/{contributionName}.xsd"里面;而解析类定义在"{configurationName}.bean-defenition-parses"里面("/"由"*"代替),如下图:

webx3.0-SpringExt

//捐献的名称和解析类
turbine-rundata-resolver=com.alibaba.citrus.turbine.dataresolver.impl.TurbineRunDataResolverFactory$DefinitionParser
parameter-resolver=com.alibaba.citrus.turbine.dataresolver.impl.ParameterResolverFactory$DefinitionParser
form-resolver=com.alibaba.citrus.turbine.dataresolver.impl.FormResolverFactory$DefinitionParser

自己实现一个Schema

1、编写bean

public class Karry {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    void execute() {
        System.out.println("Hello "+name);
    }
}

2、创建META-INF文件夹,并添加services.bean-defenition-parses文件

Karry = MyParse

3、创建解析类MyParse

public class MyPrase extends AbstractNamedBeanDefinitionParser<Karry> {
    //当不能再ID的时候,以此作为beanId
    @Override
    protected String getDefaultName() {
        // TODO Auto-generated method stub
        return "Karry";
    }
    //将name标签解析为bean属性
    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        SpringExtUtil.attributesToProperties(element, builder, "name");
    }
 
}

4、在META-INF下增加Karry.xsd文件

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="<a href="http://www.w3.org/2001/XMLSchema" targetNamespace="<a href="http://www.example.org/Karry" xmlns:tns="<a href="http://www.example.org/Karry" elementFormDefault="qualified">
    <xsd:element name="Karry">
        <xsd:complexType >
            <xsd:attribute name="name" type="xsd:string" />
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

5、在Spring配置文件中增加该Karry Bean

<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns:xsi="<a href="  xmlns:services="<a href="http://www.alibaba.com/schema/services" xmlns:beans="<a href="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="
        http://www.alibaba.com/schema/services http://localhost:8080/schema/services.xsd
        http://www.springframework.org/schema/beans http://localhost:8080/schema/www.springframework.org/schema/beans/spring-beans.xsd
    ">
    <services:Karry name="chenshuai" />
</beans:beans>

6、增加测试类

public class TestSpringExt {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ApplicationContext ctx = new XmlApplicationContext(new ClassPathResource("MySpringExt.xml"));
        Karry res = (Karry) ctx.getBean("Karry");
        res.execute();
    }
}


你可能感兴趣的:(spring,webx)