浏览 5016 次
锁定老帖子 主题:Spring2.0 可扩展XML配置初探
精华帖 (5) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-18
<mytag:datasource id="datasource" databaseType="oracle" ip="192.168.1.110" port="1521" databaseName="myDB" userName="admin" password="password" /> <mytag:ehCache id="ehcache" cache="true" maxElements="100000" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> 上面的代码中配置了两个组件,datasource和cache组件,相比普通的bean&propertiy方式,很显然,这种配置方式更直观,更易读,更重要的是,如果作为组件发布,使用者也可以很方便快捷的开始使用,而不需要关心组件的任何实现细节。 扩展XML配置大致需要一下几个步骤 1、创建一个需要扩展的组件 2、定义一个xsd文件描述组件内容 3、创建一个文件,实现BeanDefinitionParser接口,用来解析xsd文件中的定义和组件定义 4、创建一个Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器 5、编写spring.handlers和spring.schemas文件 提供一个简单的例子,来说明如何去扩展一个Spring配置,需求如下:使用自定义标签定义一个简单的bean,这个bean有一个或多个属性,标签定义完成后,可以在其他项目中用自定义标签来定义该bean。 首先,创建一个需要扩展的组件,在这里只是一个简单的bean,而且这个bean只有一个属性age. One.java package com.mysite.tag; public class One { private String age; public One(){ } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } 然后,建立一个xsd文件,来描述这个bean mytag.xsd <?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.mysite.org/schema/mytag" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.mysite.org/schema/mytag" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:element name="one"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="age" type="xsd:string" default="99999"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema> 在上面的xsd文件描述了一个新的targetNamespace,并在这个空间中定义了一个name为one的element,one有一个age属性,类型为string,默认值为99999.xsd文件是xml DTD的替代者,使用XML Schema语言进行编写,这里对xsd schema不做太多解释,有兴趣可以参考相关的资料。 创建一个Java文件,该文件实现了BeanDefinitionParser接口,用来解析xsd文件中的定义并注册到组件中。 MyBeanDefinitionParser.java package com.mysite.tag; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; public class MyBeanDefinitionParser implements BeanDefinitionParser{ public BeanDefinition parse(Element arg0, ParserContext arg1) { RootBeanDefinition def = new RootBeanDefinition(); //设置Bean Class def.setBeanClass(One.class); //注册ID属性 String id = arg0.getAttribute("id"); BeanDefinitionHolder idHolder= new BeanDefinitionHolder(def,id); BeanDefinitionReaderUtils.registerBeanDefinition(idHolder, arg1.getRegistry()); //注册age属性 String age = arg0.getAttribute("age"); BeanDefinitionHolder ageHolder= new BeanDefinitionHolder(def,age); BeanDefinitionReaderUtils.registerBeanDefinition(ageHolder, arg1.getRegistry()); def.getPropertyValues().addPropertyValue("age", age); return def; } } 上面的代码仅仅实现了一个方法public BeanDefinition parse(Element arg0, ParserContext arg1),设置相关的Bean Class,解析了对应的xsd文件,并将解析的内容注册到上下文中,同时返回一个BeanDefinition对象(BeanDefinition是Spring的bean定义,提供了bean部分的操作方法,如isSingleton()、isLazyInit()等)。 注意,id属性是一个默认的属性,可以不在xsd文件中描述,但是需要注册它,否则将无法通过getBean方法获取标签定义的bean,也无法被其他bean引用。 另外,下面代码是给bean的属性赋值,这个是不可缺少的,否则在使用标签定义时将无法获取bean属性的值。 def.getPropertyValues().addPropertyValue("age", age); 然后为组件编写一个Handler文件,扩展自NamespaceHandlerSupport,它的作用是将组件注册到Spring容器 MyNameSpaceHandler.java package com.mysite.tag; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MyNameSpaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("one",new MyBeanDefinitionParser()); } } 实际执行的过程只有一句代码,注册了一个名字为one的扩展配置,包含了MyBeanDefinitionParser所parser相关xsd的内容。 到了这里,一个Spring扩展标签已经完成,但是我们目前还没办法使用它,Spring没那么聪明,它无法知道我们在什么地方定义了哪些扩展标签,这些标签将被谁解析,这个过程要我们通过一些文件来告知Spring知道,它们就是spring.handlers和spring.schemas,它们放在META-INF目录中,Spring.jar的META-INF目录中也有同名的文件,它们的文件内容基本上是相似的,而Spring在执行过程中,如果发现其他jar文件的META-INF文件夹中包含有这两个文件,Spring将会合并它们。 spring.schemas http\://www.mysite.org/schema/mytag.xsd=com/mysite/tag/mytag.xsd spring.handlers http\://www.mysite.org/schema/mytag=com.mysite.tag.MyNameSpaceHandler spring.schemas将告诉Spring配置文件知道,如果在配置中引用http://www.mysite.org/schema/mytag.xsd,它应该去什么地方找相应的xsd文件。 而spring.handlers文件将告诉Spring,应该使用哪个Handler注册扩展标签。 现在为止,一个完整的xml扩展标签全部完成,做一个小应用测试一下。 将整个项目打包成jar文件(别忘记META-INF内的两个文件),然后新建一个项目,引用刚才打包的jar文件,并引用Spring相关文件。 需要注意,自定义xml扩展配置只有xsd方式的引用才可以使用. application.xml <?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:tag="http://www.mysite.org/schema/mytag" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.mysite.org/schema/mytag http://www.mysite.org/schema/mytag.xsd"> <tag:one id="oneBean" age="99"/> </beans> 在xml文件引用上可以看到,配置了一个名字为tag的名称空间,目标为http://www.mysite.org/schema/mytag命名空间,这个目标名称空间必须是存在于项目的引用中的(mytag.xsd中所定义的). <tag:one id="oneBean" age="99"/> 上面定义了一个id为oneBean的组件,使用了“one”扩展标签,也就是我们在handler中所注册的,组件age属性的值为99。 Main.java package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mysite.tag.One; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml"); One tag = (One) ctx.getBean("oneBean"); System.out.println("oneBean age is "+tag.getAge()); } } 运行测试程序,结果如下 oneBean age is 99 Spring的xml扩展是一个非常有用的特性,在Spring2.0的版本中也提供了一些新的标签使用,如<aop>,<tx>等,但就目前来讲受大家关注程度并不高,我想大部分使用Spring的开发人员都在使用Spring开发企业应用,而Spring所提供的<bean />定义的方式对于开发人员来说已经能够满足需要,但是如果看的更远一些,在Spring以后的发展过程中,xml扩展应该会成为spring的核心特性之一,或许到时大家会习惯这样的方式来编写Spring配置文件吧 <XXCompany:XXXModule id=""> ... ... 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-07-18
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="com.interface21.spring2.ioc.Person" p:name="Tony" p:age="53" p:house-ref="number10" /> <bean class="com.interface21.spring2.ioc.House" id="number10" p:name="10 Downing Street"/> </beans> 对于简单的应用可以用p标签就好了。 自定意扩展应该用在更多的高级应用上 |
|
返回顶楼 | |
发表时间:2007-07-18
楼上这么快,
p标签和<aop>、<tx>这些标签一样,是Spring2.0原本就提供的,而非自定义标签,本文的目的也只是说明自定义标签的定义及使用方法 ![]() |
|
返回顶楼 | |