Spring 2.0版本支持扩展XML配置,着实兴奋了一下,在我看来,Spring作为目前最流行的框架,不能扩展用户自定义的配置,实在是Spring的一个很不爽的地方,的方式用起来比较通用,起码到目前为止符合大部分人的使用习惯,并且能完成Spring所有的配置操作,但是对于第三方的提供商或则会经常扩展Spring功能的开发者来说,使用这样的配置方式或许不是他们最想要的,他们需要使组件的配置更加直观、易阅读、易扩展……试想使用下面的配置方式。
<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文件中的定义并注册到组件中。
#p#
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方式的引用才可以使用。
#p#
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的版本中也提供了一些新的标签使用,如,等,但就目前来讲受大家关注程度并不高,我想大部分使用Spring的开发人员都在使用Spring开发企业应用,而Spring所提供的定义的方式对于开发人员来说已经能够满足需要,但是如果看的更远一些,在Spring以后的发展过程中,xml扩展应该会成为spring的核心特性之一,或许到时大家会习惯这样的方式来编写Spring配置文件吧!
<XXCompany:XXXModule id="">
...
...
分享到:
相关推荐
Spring 2.0扩展了容器的功能,如支持更多的bean定义元数据,增强了事件传播机制,以及引入了可扩展的bean后处理器。 十、Spring与Java EE集成 Spring 2.0强化了与Java EE规范的集成,包括JTA事务管理、EJB3集成以及...
《Spring2.0宝典源代码》是一份珍贵的学习资源,由知名作者李刚编写,旨在深入解析Spring框架的2.0版本。这份源代码集合是配合书籍《Spring2.0宝典》使用的,读者可以通过实际操作代码来理解和掌握Spring 2.0的核心...
### SPRING2.0开发详解 #### 一、Spring框架简介 Spring框架是一个开源的Java平台,用于构建企业级应用程序和服务。它最初由Rod Johnson在2004年创建,并随着时间的发展不断壮大和完善。Spring 2.0版本是Spring...
Spring 2.0引入了注解驱动的Web MVC开发,例如@Controller、@RequestMapping、@RequestParam等,大大简化了控制器的编写,减少了XML配置。 六、Spring Portlet MVC Spring 2.0也扩展到了portlet领域,提供了Portlet...
Spring 2.0 是Spring框架的一个重要版本,它在Java企业级应用开发中扮演着核心角色。这个版本引入了许多新特性,增强了框架的功能和灵活性。本文将深入探讨Spring 2.0源代码中的关键知识点,帮助开发者理解其内部...
Spring作为Java领域的主流框架,其2.0版本是一个重要的里程碑,引入了许多创新特性,提升了框架的灵活性和可扩展性。 在Spring 2.0中,最重要的更新之一是AOP(面向切面编程)的增强。这一版本引入了基于注解的AOP...
Spring 2.0 版本进一步扩展了其功能,并提供了更多的特性来支持企业级应用的开发。 #### 二、Spring 的核心特性 1. **依赖注入(DI)**:通过依赖注入机制,Spring 框架帮助开发者管理对象之间的依赖关系,使得...
6. **Bean配置**:XML配置是Spring 2.0的主要配置方式,但同时也引入了基于注解的配置,允许开发者在类或方法上使用注解来声明bean的属性和依赖。这种方式减少了XML配置文件的复杂性,提高了代码的可读性。 7. **...
2.0版本增强了对构造器注入和 Setter 注入的支持,并引入了基于注解的配置,使得代码更简洁,减少了XML配置文件的复杂性。例如,使用`@Autowired`注解可以自动匹配并注入相应的bean。 其次,Spring 2.0在面向切面...
在Spring 2.0中,DI得到了增强,支持了基于注解的配置,这使得XML配置文件可以显著减少,代码更加简洁易读。 另一个重要特性是AOP(面向切面编程),Spring的AOP模块允许开发者定义横切关注点,如日志记录、事务...
Spring 2.0引入了对portlet开发的支持,可以与portlet容器(如Liferay)无缝集成,扩展了Spring的应用范围。 七、国际化和本地化支持 Spring 2.0提供了对国际化和本地化的良好支持,通过ResourceBundle和...
《Spring 2.0中文参考手册》是一本深入解析Spring框架的重要资料,它全面覆盖了Spring 2.0版本的核心特性和应用场景。Spring作为一个轻量级的Java企业级应用框架,以其模块化、松耦合的设计理念,已经成为现代Java...
在Spring Cloud 2.0版本中,Eureka Server的配置相比1.x版本确实有了一些显著的变化,尤其是在结合Spring Security进行安全设置时。Spring Cloud Eureka是Netflix Eureka的Spring Boot实现,它为微服务架构提供了...
标题 "spring2.0学习笔记+spring定时任务" 暗示了我们即将探讨的是关于Spring框架2.0版本的学习心得以及如何在Spring中配置和使用定时任务。在这个主题下,我们将深入理解Spring的核心概念,特别是它在企业级Java...
4. **XML配置增强**:Spring 2.0的XML配置文件引入了命名空间,如`<context:component-scan>`用于自动扫描和注册bean,`<tx:annotation-driven>`用于启用基于注解的事务管理,使得配置更加简洁明了。 5. **注解驱动...
1. **依赖注入(Dependency Injection, DI)**:Spring 2.0通过XML配置或注解来实现对象之间的依赖关系管理,降低了组件间的耦合度,使得代码更易于测试和维护。 2. **面向切面编程(Aspect-Oriented Programming, ...
Spring 2.0 是 Spring Framework 的一个重要里程碑,它引入了一系列的新特性和改进,极大地提升...通过控制反转容器的改进,XML 配置的简化,以及面向切面编程的支持,Spring 2.0 成为了现代 Java 应用开发的重要基石。
1. **依赖注入**:在Spring 2.0中,依赖注入通过XML配置或基于注解的方式实现,使组件之间的耦合度降低,提高了代码的可测试性和可维护性。开发者可以更灵活地管理对象的生命周期和依赖关系。 2. **AOP**:Spring ...