SpringExt 扩展原理
来源:互联网 发布:windows 安全配置基线 编辑:程序博客网 时间:2024/05/20 18:45
这篇文章是基于webx框架官方文档整理的。具体的请参见webx官方文档。
首先先弄明白在面向对象的设计中比较核心的一个原则——OCP(Open-Closed Principle),也就是开闭原则。
最早描述OCP的是OCP原则的提出者Bertrand Meyer,他在他的著作《Object Oriented Software Construction》中提出了OCP原则:“Software entities should be open for extension,but closed for modification”,也就是“软件实体应当对扩展开放,对修改关闭”。简单点说就是如果原有功能没有什么问题而需要扩展新的功能,那么就应该在不修改原有代码的基础上进行功能的扩展。
下面将要讲到的SpringExt就是为了符合OCP原则而对Spring的一种扩展。
SpringExt装配服务
webx中有一个非常有用的ResourceLoadingService,它可以从各种输入源中(比如FileSystem、Classpath、Webapp等等)读取源文件的一种服务。下面就以这个服务为例来说明一下SpringExt是如何对Spring进行扩展使其符合OCP原则。 ResourceLoadingService的结构如下所示
下面我们以这个为例来看一下Spring Beans是如何装载Resource Loading服务的。
Spring2.0之前只能使用如下的xml配置来进行装载
<bean id="resourceLoadingService" class="com.alibaba...ResourceLoadingServiceImpl"> <property name="mappings"> <map> <entry key="/file" value-ref="fileLoader" /> <entry key="/webroot" value-ref="webappLoader" /> </map> </property> </bean> <bean id="fileLoader" class="com.alibaba...FileResourceLoader"> <property name="basedir" value="${user.home}" /> </bean> <bean id="webappLoader" class=" com.alibaba...WebappResourceLoader" />
上面的配置如果有点Spring基础的都应该看的懂,典型的IOC。ResourceLoadingServiceImpl并不依赖FileResourceLoader和WebappResourceLoader,它只依赖它们的接口ResourceLoader。至于如何创建FileResourceLoader、WebappResourceLoader、需要提供哪些参数,这些都由spring来负责。
Spring本身并不了解如何创建ResourceLoader对象、用哪些参数、如何注入等等。但并不是说没有人关注这些。这些事情由装配者(程序员)来解决,也就是写这些配置文件的人。
先定义两个角色:服务提供者、服务使用者。ResourceLoadingService的作者是服务提供者,也就是写ResourceLoadingService服务的人。使用ResourceLoadingService的人就是服务使用者,服务使用者利用Spring吧ResourceLoadingService和ResourceLoader装配在一起。
这种配置文件的方式可能会带来比较一些问题。
1、没有检验机制,只能在运行时发现错误。
2、除了阅读源代码,无从得知更多的约束条件。
3、如果服务的实现改变了,这个配置文件可能会失败。因为从bean的class属性可以看出,bean是直接依赖于具体的实现的。
Spring Schema
关于Xml Schema可以参考http://www.w3school.com.cn/schema/index.asp,这里不再赘述。Spring2.0之后可以用Spring Schema改写为下面:
<resource-loading id="resourceLoadingService" xmlns="http://www.alibaba.com/schema/services/resource-loading"> <resource pattern="/file"> <file-loader basedir="${user.home}" /> </resource> <resource pattern="/webroot"> <webapp-loader /> </resource></resource-loading>
首先说一下这个配置文件的优点。
1、简洁易读。
2、可验证。
3、可以包含约束条件。
4、服务的细节对装配者隐藏。这也是最重要的一点,从配置文件中可以看出,并没有引用具体的实现类。那么当服务的实现类被改变时,只要Xml Schema没有变,Spring的配置就不会受到影响。
虽然配置文件中没有体现出具体的实现,但是Spring需要知道这些内容。那Spring是怎么知道的?
每个schema都会有一个解释器。解释器是有服务的开发者提供的。解释器会将符合标准的xml schema转换成Spring能读懂的beans定义。
上面这个图就很清晰了。服务的使用者不知道API的具体实现,这样的三层结构相当于减少了耦合。
但是,Spring Schema也存在一个问题,就是无法扩展。比如,下面的配置文件就是错误的,因为Spring Schema无法解析。(多了db)
<resource-loading id="resourceLoadingService" xmlns="http://www.alibaba.com/schema/services/resource-loading"> <resource pattern="/file"> <file-loader basedir="${user.home}" /> </resource> <resource pattern="/webroot"> <webapp-loader /> </resource> <resource pattern="/db"> <database-loader connection="jdbc:mysql:mydb" /> </resource></resource-loading>我们需要添加新的加载器,但是schema并没有预料到这种情况,所以schema中并没有这方面的信息,因此无法解析上面的配置文件。如果我们要求Spring Schema来解析新的加载器,那必须要修改Schema的定义文件。很显然,这违背了OCP原则。
SpringExt Schema
SpringExt Schema可以将Spring Schema进行进一步的更改:
<resource-loading id="resourceLoadingService" xmlns="http://www.alibaba.com/schema/services" xmlns:loaders="http://www.alibaba.com/schema/services/resource-loading/loaders"> <resource pattern="/file"> <loaders:file-loader basedir="${user.home}" /> </resource> <resource pattern="/webroot"> <loaders:webapp-loader /> </resource> <resource pattern="/db"> <loaders:database-loader connection="jdbc:mysql:mydb" /> </resource></resource-loading>
上面的配置文件就可以正确解析,但是并没有对原有的schema做修改。仔细对比一下这两个配置文件,可以发现后一个配置文件中出现了两个xmlns,这也导致了标签的相关书写也不太一样,比如loaders:file-loader。
SpringExt Schema的原理
下面是resource-loading.xsd的片段:<xsd:element name="resource" type="ResourceLoadingServiceResourceType"><xsd:complexType name="ResourceLoadingServiceResourceType"> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:any namespace="http://www.alibaba.com/schema/services/resource-loading/loaders" /> </xsd:choice> <xsd:attribute name="pattern" type="xsd:string" use="required" /></xsd:complexType>熟悉schema规则的很容易明白SpringExt是如何进行扩展的,关键在<xsd:any>这个标签。
总结性的讲,在上面的例子中,Spring Schema中定义了一个namespace,而SpringExt Schema定义了两个namespace。这就是关键所在,SpringExt把需要扩展的schema进行了分离,如果我们需要进行扩展,那么添加一个新的xsd文件即可。
- SpringExt 扩展原理
- Webx SpringExt
- webx - SpringExt
- SpringExt 源码学习
- springExt(转载)
- 扩展欧几里得原理
- 扩展欧几里德原理
- PHP扩展安装原理
- WebX 3.0学习笔记(五):SpringExt
- 安装SpringExt以查看schema文件
- kmp和扩展kmp原理
- [ lucene扩展 ] spellChecker原理分析
- Volley(二),扩展 && 原理
- 扩展星历原理及应用
- 扩展欧几里得原理与模板
- 3314 扩展gcd 及 扩展gcd的原理
- PHP安装扩展原理+php7的redis扩展安装
- 32bit oracle 扩展SGA原理
- dom4j读写xml文件
- UIImage任意形状的不规则裁剪
- 如何让Extjs弹出window窗口后背景窗口变灰(即不可编辑)
- JAVA中split()关于.的问题
- installshield2014激活步骤
- SpringExt 扩展原理
- html5手机摇一摇效果
- 解决WordPress加载缓慢的方法
- HBase 使用场景和成功案例
- JAVA 基础 (四) IO操作
- 在Asp.Net中操作PDF – iTextSharp-列表
- 调用opencv的detectMultiScale函数时报错
- PHP5.5在IIS7.5上无法运行,改用5.3版本后正常
- oracle——索引组织表