dubbo源码解析(五) dubbo中的spring使用

dubbo启动spring的代码如下:



dubbo采用了spring自定义的schema。

首先简单介绍下spring自定义的schema。

完成一个自定义配置一般需要以下步骤:
1.设计配置属性和JavaBean 
2.编写XSD文件 
3.编写NamespaceHandler和BeanDefinitionParser完成解析工作 
4.编写spring.handlers和spring.schemas串联起所有部件 

5.在Bean文件中应用 

下面是一个简单的例子,整体结构如下:


1)设计配置属性和JavaBean

package springshema;

public class User {
    private String id;
    private String name;
    private String sex;
    private int age;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2)编写XSD文件

为上一步设计好的配置项编写XSD文件,XSD是schema的定义文件,配置的输入和解析输出都是以XSD为契约,本例中XSD如下:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>


<xsd:schema xmlns="http://www.cnblogs.com/eric-lin/schema/user"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            xmlns:tool="http://www.springframework.org/schema/tool"
            targetNamespace="http://www.cnblogs.com/test/schema/user"
            elementFormDefault="qualified" attributeFormDefault="unqualified">


    <xsd:import namespace="http://www.springframework.org/schema/beans" />
    <xsd:import namespace="http://www.springframework.org/schema/tool" />


    <xsd:element name="user">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="name" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>姓名</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>


                    <xsd:attribute name="sex" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>性别</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>


                    <xsd:attribute name="age" type="xsd:int">
                        <xsd:annotation>
                            <xsd:documentation>年龄</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
3)编写NamespaceHandler和BeanDefinitionParser完成解析工作

package springshema;


import org.springframework.beans.factory.xml.NamespaceHandlerSupport;


public class UserNamespaceHandler extends NamespaceHandlerSupport {


    public void init() {
        registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
    }
}
package springshema;


import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;


public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {


    @Override
    protected Class<?> getBeanClass(Element element) {
        return User.class;
    }


    @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        String id = element.getAttribute("id");
        String name = element.getAttribute("name");
        String sex = element.getAttribute("sex");
        int age = Integer.parseInt(element.getAttribute("age"));


        bean.addPropertyValue("id", id);
        bean.addPropertyValue("name", name);
        bean.addPropertyValue("sex", sex);
        bean.addPropertyValue("age", age);
    }
}
4)编写spring.handlers和spring.schemas串联起所有部件

上面几个步骤走下来会发现开发好的handler与xsd还没法让应用感知到,就这样放上去是没法把前面做的工作纳入体系中的,spring提供了spring.handlers和spring.schemas这两个配置文件来完成这项工作,这两个文件需要我们自己编写并放入META-INF文件夹中,这两个文件的地址必须是META-INF/spring.handlers和META-INF/spring.schemas,spring会默认去载入它们,本例中spring.handlers如下所示:

http\://www.cnblogs.com/test/schema/user=springshema.UserNamespaceHandler

spring.schemas如下所示:

http\://www.cnblogs.com/test/schema/user/user.xsd=META-INF/user.xsd

5)在Bean文件中应用

到此为止一个简单的自定义配置以完成,可以在具体应用中使用了。使用方法很简单,和配置一个普通的spring bean类似,只不过需要基于我们自定义schema,本例中引用方式如下所示:

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:test="http://www.cnblogs.com/test/schema/user"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.cnblogs.com/test/schema/user
    http://www.cnblogs.com/test/schema/user/user.xsd">


    <test:user id="eric" name="123" sex="male" age="28" />


</beans>

最后就可以在具体程序中使用基本的bean载入方式来载入我们的自定义配置对象了,如:

package springshema;


import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestSpringSchema {


    @SuppressWarnings("resource")
    @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");


        User user = (User) context.getBean("eric");
        System.out.println(user.getId());
        System.out.println(user.getName());
        System.out.println(user.getSex());
        System.out.println(user.getAge());
    }
}

下面是dubbo中spring  schema配置


下面是dubbo的provider的配置

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <bean id="demoService" class="com.DemoServiceImpl" />
    <dubbo:service interface="com.DemoService" ref="demoService" />
</beans>

在dubbo 的使用中,扩展了一个dubbo 的标签. 可以看到这个dubbo 的标签的xsd 的,url 是在 “http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd” , 但是这个网址并无实际内容, 原因是spring extends 会默认加载这classpath 下的这两个文件 META-INF/spring.handlers和META-INF/spring.schemas ,当碰到 dubbo 标签时,会调用DubboNamespaceHandler这个类来处理。DubboNamespaceHandler 实现了父类中的init方法,并定义了自己的DubboBeanDefinitionParser。最终将其转换成BeanDefinition,提供spring容器实例化使用。

进入DubboNamespaceHandler这个类:


针对dubbo的provider的配置,通过解析service标签,生成BeanDefinition放入spring容器。我们可以以接口全名为参数从spring容器中获取一个serviceBean对象。下面做一个验证:

通过以下代码可以获取一个serviceBean对象:

context.getBean("com.alibaba.dubbo.demo.DemoService")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值