Spring配置文件解析

解析配置

解析配置,是Dubbo服务启动的第一步,基于Spring配置结合的框架都是从这一步开始启动的(包括之前提到的Motan);
Dubbo官方文档中提到:

初始化过程的第一步是从解析服务开始的,基于 dubbo.jar 内的 META-INF/spring.handlers 配置,
Spring 在遇到 dubbo 名称空间时,会回调 DubboNamespaceHandler。所有 dubbo 的标签,都统一用 DubboBeanDefinitionParser 进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对象。

真正想了解一只青蛙,传统的解剖不是办法,更好的方式是构造一只青蛙

所以想要了解这个过程,最好的方式是实现一个这样的过。
试想,在使用Dubbo的时候,配置各种标签:dubbo:application、dubbo:protocol、dubbo:service 等等;这些配置最终是如何转化成Dubbo框架的对象的;本文将试着照虎画猫,实现这样的一个功能。

目标:不使用传统的<bean>配置,使用自己定义的标签和命名空间来创建一个自定义的对象

创建MAVEN项目

创建项目过程,此处略过,增加spring的依赖:

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>

创建目标对象

也就是我们需要通过xml配置,生成出什么类型的对象,此处略过;

创建XML约束文件xsd:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.irvingsun.cn/schema/foo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.irvingsun.cn/schema/foo">
    <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="abstractPerson">
        <xsd:attribute name="id" type="xsd:string" use="required"/>
        <xsd:attribute name="firstname" type="xsd:string" use="required" />
        <xsd:attribute name="lastname" type="xsd:string" use="required" />
        <xsd:attribute name="age" type="xsd:int" use="required" />
        <xsd:attribute name="gender" type="xsd:string" use="required"/>
        <xsd:attribute name="address" type="xsd:string" />
    </xsd:complexType>
    <xsd:element name="person" type="abstractPerson"/>
</xsd:schema>

这个约束文件表示,我们需要创建一个名为person的标签,它有id、firstname、lastname、age等属性。该文件位于resources/META-INF/目录下。
同时在改目录下创建spring.schemas文件,该文件将告知spring,约束文件映射的本地具体位置,如果找不到,它将访问这个http地址查找;
http://www.irvingsun.cn/schema/foo.xsd=META-INF/foo.xsd

编写XML配置

此时,我们就可以通过这个xsd文件约束来创建XML配置文件了:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:foo="http://www.irvingsun.cn/schema/foo"
      xmlns="http://www.springframework.org/schema/beans"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.irvingsun.cn/schema/foo http://www.irvingsun.cn/schema/foo.xsd">

    <foo:person id = "idx" firstname="sun" lastname="way" age="1" gender="male" />

</beans>

我们配置了一个person标签,并且给属性赋值;

通过Spring自动解析

  • 创建Namespace解析处理器
public class PersonNamespaceHandler extends NamespaceHandlerSupport{
    public void init() {
        registerBeanDefinitionParser("person", new FooBeanDefinitionParser(Person.class, true));
    }
}

此处注册了一个BeanDefinition解析器,用来解析person标签:

public class FooBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    protected Class getBeanClass(Element element) {
        return Person.class;
    }
    protected void doParse(Element element, BeanDefinitionBuilder bean) {
            String firstName = element.getAttribute("firstname");
            String lastName = element.getAttribute("lastname");
            String age = element.getAttribute("age");
            String id = element.getAttribute("id");
            String address = element.getAttribute("address");

        if(!StringUtils.isEmpty(firstName)){
            bean.addPropertyValue("firstName",firstName);
            }
            if(!StringUtils.isEmpty(lastName)){
                bean.addPropertyValue("lastName",lastName);
            }
            if(!StringUtils.isEmpty(id)){
                bean.addPropertyValue("id",id);
            }
            if(!StringUtils.isEmpty(address)){
                bean.addPropertyValue("address",address);
            }
            if(!StringUtils.isEmpty(age)){
                bean.addPropertyValue("age",Integer.parseInt(age));
            }
    }
}

从Element对象中加载出我们配置的值,并且返回BeanDefinition对象(父类中);

使用配置

和平时使用Spring的方式一样,通过加载XML配置文件:

public static void main( String[] args )
    {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"});
//        context.start();
        context.getBean(Person.class);
    }

回到开始时提到的,和Spring集成的情况,Dubbo启动,根据这种方式来将我们配置的参数,实例化为框架中对应的对象。

-EOF-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值