分布式服务Dubbo从入门到"精通"之自定义Schema

相信,大多数小伙伴们仔细阅读了上篇文章并翻阅了Dubbo的部分代码,一定会对其有一个大体的了解吧。

当然,不了解也没问题,反正不是我不想让你不了解。好了,言归正传,今天呢,与大家分享的主题如题目所述《如何自定义Schema》。

01164137-7f0eb33f471341c0afec0dace55c06c2.png

项目大体如下(请自行忽略报错和它的丑):

12345.png

小伙伴们,有么有发现跟上一篇的结构其实是差不多的,唯一的差别是,这个只是个demo。

定义一个类,ServiceConfig:

public class ServiceConfig {
    private String interfaceVal;
    private Object ref;

    public ServiceConfig() {
        super();
    }

    public ServiceConfig(String interfaceVal, Object ref) {
        super();
        this.interfaceVal = interfaceVal;
        this.ref = ref;
    }

    public String getInterfaceVal() {
        return interfaceVal;
    }

    public void setInterfaceVal(String interfaceVal) {
        this.interfaceVal = interfaceVal;
    }

    public Object getRef() {
        return ref;
    }

    public void setRef(Object ref) {
        this.ref = ref;
    }

}

定义一个人 PeopleConfig:

public class PeopleConfig {
    private String name;
    private String sex;
    private Integer age;
    
    public PeopleConfig() {
        super();
    }
    public PeopleConfig(String name, String sex, Integer age) {
        super();
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    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 Integer getAge() {
        return age;
    }

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

处理器 RpcBeanDefinitionParser:

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

import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;

public class RpcBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    private Class<?> beanClass;

    public RpcBeanDefinitionParser(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected Class getBeanClass(Element element) {
        return this.beanClass;
    }

    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        if (ServiceConfig.class.equals(this.beanClass)) {
            String interfaceVal = element.getAttribute("interface");
            String refVal = element.getAttribute("ref");
            Object reference = new RuntimeBeanReference(refVal);

            bean.addPropertyValue("interfaceVal", interfaceVal);
            bean.addPropertyValue("ref", reference);
        }else if(PeopleConfig.class.equals(this.beanClass)){
            String name = element.getAttribute("name");
            String sex = element.getAttribute("sex");
            String age = element.getAttribute("age");
            bean.addPropertyValue("name", name);
            bean.addPropertyValue("sex", sex);
            bean.addPropertyValue("age", age);
        }
    }
}

控制器 RpcNamespaceHandler:

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

import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;

public class RpcNamespaceHandler extends  NamespaceHandlerSupport {
    //初始化配置
    public void init() {
        registerBeanDefinitionParser("service", new RpcBeanDefinitionParser(ServiceConfig.class));
        registerBeanDefinitionParser("people", new RpcBeanDefinitionParser(PeopleConfig.class));
    }
}

当然,这里我还建了一个service:

public interface IBeanService {
    String say();
}

public class BeanServiceImpl implements IBeanService {
    @Override
    public String say() {
        return "科帮网欢迎你";
    }
}

好了,接下来就开始我们的配置吧:
spring.schemas:

http\://code.itstyle.com/schema/itstyle/itstyle.xsd=META-INF/itstyle.xsd

spring.handlers:

http\://code.itstyle.com/schema/itstyle=com.itstyle.rpc.cinfig.spring.schema.RpcNamespaceHandler

itstyle.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://code.itstyle.com/schema/itstyle"
    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://code.itstyle.com/schema/itstyle">
    
    <!-- 向一个文档添加带有不同目标命名空间的多个 schema  -->
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
    <xsd:import namespace="http://www.springframework.org/schema/beans"/>
    <xsd:import namespace="http://www.springframework.org/schema/tool"/>
  
  <xsd:complexType name="serviceType">
     <xsd:complexContent>
        <xsd:extension base="beans:identifiedType" >
             <xsd:attribute name="interface" type="xsd:string" />
             <xsd:attribute name="ref" type="xsd:string" />
         </xsd:extension>
      </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="service" type="serviceType">
        <xsd:annotation> 
            <xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation> 
        </xsd:annotation>
  </xsd:element>
  
  <xsd:complexType name="peopleType">
     <xsd:complexContent>
        <xsd:extension base="beans:identifiedType" >
             <xsd:attribute name="name" type="xsd:string" />
             <xsd:attribute name="sex"  type="xsd:string" />
             <xsd:attribute name="age"  type="xsd:string" />
         </xsd:extension>
      </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="people" type="peopleType">
        <xsd:annotation> 
            <xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation> 
        </xsd:annotation>
  </xsd:element>
</xsd:schema>

spring-itstyle.xml:

发图,是让大家注意重点
34567.png

<?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:itstyle="http://code.itstyle.com/schema/itstyle"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://code.itstyle.com/schema/itstyle
        http://code.itstyle.com/schema/itstyle/itstyle.xsd
        ">
    <bean id="say" class="com.itstyle.rpc.service.impl.BeanServiceImpl"></bean>
    <itstyle:service id="service" interface="com.itstyle.rpc.service.IBeanService" ref="say"/>
    
    <itstyle:people id="xiaoming" name="小明" sex="男" age="10"/>
</beans>

好了,最后我们写一个测试ItstyleSchema:

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

import com.itstyle.rpc.cinfig.PeopleConfig;
import com.itstyle.rpc.cinfig.ServiceConfig;
import com.itstyle.rpc.service.IBeanService;

public class ItstyleSchema {
    @SuppressWarnings("resource")
    @Test
    public void test() {

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "classpath:spring-itstyle.xml");
        context.start();
        //服务接口
        ServiceConfig service = (ServiceConfig) context.getBean("service");
        IBeanService  service1 = (IBeanService) service.getRef();
        //实现方法
        System.out.println(service1.say());
        //xiaoming
        PeopleConfig people = (PeopleConfig) context.getBean("xiaoming");
        System.out.println("我是:"+people.getName());
    }
}

4567.png

qrcode_for_gh_bf7a27ade681_258.jpg

作者: 小柒

出处: https://blog.52itstyle.com

分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大家指正,共同进步。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 如有问题, 可邮件(345849402@qq.com)咨询。