signed

QiShunwang

“诚信为本、客户至上”

聊聊Spring源码的SpringUtil【附录:XML语法】【RPC实践案例之编写XSD】

2021/6/3 16:28:42   来源:

一、背景

在写RPC框架中,借鉴了dubbo的思想,而dubbo的实现基于Spring Schema。所以需要了解下如何在Spring的基础上扩展Spring Schema。

二、收益

可以更好的理解Spring中的schema语法,以及对于集成Spring的过程中的自己编写框架可以更加合理。

三、原理

3.1、XML语法

这一部分列出了与Spring核心容器相关的XML模式。

3.2、Schema工具

举个例子util标记处理常见的实用程序配置问题,如配置集合、引用常量等。要使用util模式中的标记,需要在springxml配置文件的顶部有以下序言协议来声明:

<?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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <!-- bean definitions here -->

</beans>

那么现在我要模仿dubbo来制定自己的Spring Schema如何写XSD呢?基于上面可以写如下内容:
我的项目名称为xcxyz-mini-dubbo,然后制定XML的Spring Schema为miniDubbo.

<?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:miniDubbo="http://www.xcxyz-mini-dubbo.com/schema/remote-service"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.xcxyz-mini-dubbo.com/schema/remote-service http://www.xcxyz-mini-dubbo.com/schema/remote-service.xsd">
</beans>

3.2.1、util:constant/

之前配置

<bean id="..." class="...">
    <property name="isolation">
        <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
                class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
    </property>
</bean>

上面的配置使用springfactorybean实现FieldRetrievingFactoryBean,将bean上隔离属性的值设置为java.sql.Connection.TRANSACTION\u SERIALIZABLE常量的值。这一切都很好,但有点冗长,而且(不必要地)将Spring的内部管道暴露给最终用户。
下面的基于XML模式的版本更加简洁,并且清楚地表达了开发人员的意图(“inject this constant value”),而且读起来更好。

<bean id="..." class="...">
    <property name="isolation">
        <util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
    </property>
</bean>

从字段值设置bean属性或构造函数参数
FieldRetrievingFactoryBean是检索静态或非静态字段值的FactoryBean。它通常用于检索公共静态final常量,然后可用于为另一个bean设置属性值或构造函数arg。
下面的示例演示了如何使用staticField属性公开静态字段:

<bean id="myField"
        class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>

还有一个方便的用法表单,其中静态字段被指定为bean名称:

<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
        class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>

这确实意味着在bean id是什么方面不再有任何选择(因此引用它的任何其他bean也必须使用这个较长的名称),但是这种形式的定义非常简洁,并且作为内部bean使用非常方便,因为不必为bean引用指定id:

<bean id="..." class="...">
    <property name="isolation">
        <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
                class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
    </property>
</bean>

如何注入

package javax.persistence;

public enum PersistenceContextType {

    TRANSACTION,
    EXTENDED
}

给属性设置值

package example;

public class Client {

    private PersistenceContextType persistenceContextType;

    public void setPersistenceContextType(PersistenceContextType type) {
        this.persistenceContextType = type;
    }
}

定义实体bean

<bean class="example.Client">
    <property name="persistenceContextType" value="TRANSACTION"/>
</bean>

3.2.2、util:property-path/

3.2.3、util:properties/

3.2.4、util:list/

3.2.5、util:map/

3.2.6、util:set/

3.3、AOP Schema

3.4、Context Schema

3.5、Beans Schema

四、资料

Spring的XML语法官网