`
longgangbai
  • 浏览: 7356680 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring 2.0自定义xml 标记

阅读更多

 

在spring 2.0 中,增加了自定义xml标记这一重大的功能。下面主要看一下spring 2.0实现这一功能的主要相关类:

NamespaceHandlerResolver(接口)
由DefaultBeanDefinitionDocumentReader使用,用于定位NamespaceHandler,指定特定的命名空间uri

实现类:
DefaultNamespaceHandlerResolver

通过map 保存所有的对应关系
默认使用spring.handlers文件来保存所有的handlers
可以定义其他的location 如:

String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";
NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), location);

NamespaceHandler(接口)

基础接口,用于DefaultBeanDefinitionDocumentReader处理自定义命名空间。
方法:
void init();
由DefaultBeanDefinitionDocumentReader调用在构造完后但在解析自定义元素前。

BeanDefinition parse(Element element, ParserContext parserContext);
解析指定的元素。

BeanDefinitionHolder decorate(Node element,
BeanDefinitionHolder definition,
ParserContext parserContext);
执行相应的修饰。

实现类:

NamespaceHandlerSupport(抽象类)

主要的三个方法:
protected final void registerBeanDefinitionDecorator(
String elementName,
BeanDefinitionDecorator decorator)
注册decorator,通过element

protected final void registerBeanDefinitionDecoratorForAttribute(
String attributeName,
BeanDefinitionDecorator decorator)
注册decorator,通过attr

protected final void registerBeanDefinitionParser(
String elementName,
BeanDefinitionParser parser)
注册BeanDefinitionParser,通过element

实际的操作由具体的BeanDefinitionDecorator 或者BeanDefinitionParser 执行

BeanDefinitionDecorator(接口)

装饰相关的自定义属性。

AbstractInterceptorDrivenBeanDefinitionDecorator
用于注册相应的Interceptor bean 定义,使用aop代理

其他类:

PluggableSchemaResolver,用于自定义相关的schema,默认的schema 保存于spring.schemas文件中

可以通过覆盖resolveEntity方法来装载相应的自定义xsd文件

主要的执行类:

XmlBeanDefinitionReader

用于处理相应的读取工作,其实主要的工作委派给BeanDefinitionDocumentReader

实际的类,就介绍到这,下一节通过实例来说明如何定义自定义xml 元素

查看本文来源

看了spring test 用例,其实实现这一功能还算比较简单,主要分以下的步骤,具体的实例可以去参考spring 自带的testcase

首先定义相关xsd文件,用于验证相应的行为:

主要增加了4个自定义元素和1个属性:

 

xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/beans/test"
elementFormDefault="qualified">
接着定义handler映射文件:customNamespace.properties

 

http://www.springframework.org/schema/beans/test=org.springframework.beans.factory.xml.support.TestNamespaceHandler

定义Handler:

主要注册相应的解析类和装饰类

 

publicclass TestNamespaceHandler extends NamespaceHandlerSupport {

publicvoid init() {

//相对于每个xsd中定义的元素

registerBeanDefinitionParser("testBean", new TestBeanDefinitionParser());

registerBeanDefinitionDecorator("set", new PropertyModifyingBeanDefinitionDecorator());

registerBeanDefinitionDecorator("debug", new DebugBeanDefinitionDecorator());

registerBeanDefinitionDecorator("nop", new NopInterceptorBeanDefinitionDecorator());

registerBeanDefinitionDecoratorForAttribute("object-name", new ObjectNameBeanDefinitionDecorator());

}

}

 

定义各个解析类:

privatestaticclass TestBeanDefinitionParser implements BeanDefinitionParser {

public BeanDefinition parse(Element element, ParserContext parserContext) {

RootBeanDefinition definition = new RootBeanDefinition();

definition.setBeanClass(TestBean.class);

 

MutablePropertyValues mpvs = new MutablePropertyValues();

mpvs.addPropertyValue("name", element.getAttribute("name"));

mpvs.addPropertyValue("age", element.getAttribute("age"));

definition.setPropertyValues(mpvs);

 

parserContext.getRegistry().registerBeanDefinition(element.getAttribute("id"), definition);

 

returnnull;

}

}

privatestaticclassPropertyModifyingBeanDefinitionDecorator implements BeanDefinitionDecorator {

public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition,

ParserContext parserContext) {

Element element = (Element)node;

BeanDefinition def = definition.getBeanDefinition();

 

MutablePropertyValues mpvs = (def.getPropertyValues() == null) ?

new MutablePropertyValues() : def.getPropertyValues();

mpvs.addPropertyValue("name", element.getAttribute("name"));

mpvs.addPropertyValue("age", element.getAttribute("age"));

 

((AbstractBeanDefinition) def).setPropertyValues(mpvs);

return definition;

}

}

privatestaticclassDebugBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator {

 

protected BeanDefinition createInterceptorDefinition(Node node) {

returnnew RootBeanDefinition(DebugInterceptor.class);

}

}

privatestaticclassNopInterceptorBeanDefinitionDecorator extends

AbstractInterceptorDrivenBeanDefinitionDecorator {

 

protected BeanDefinition createInterceptorDefinition(Node node) {

returnnew RootBeanDefinition(NopInterceptor.class);

}

}

privatestaticclassObjectNameBeanDefinitionDecorator implements BeanDefinitionDecorator {

public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition,

ParserContext parserContext) {

Attr objectNameAttribute = (Attr)node;

definition.getBeanDefinition().setAttribute("objectName", objectNameAttribute.getValue());

return definition;

}

}

 

可以定义EntityResolver,用于验证相应的xsd

privateclass DummySchemaResolver extends PluggableSchemaResolver {

 

public DummySchemaResolver() {

super(CustomNamespaceHandlerTests.this.getClass().getClassLoader());

}

 

public InputSource resolveEntity(String publicId, String systemId) throws IOException {

InputSource source = super.resolveEntity(publicId, systemId);

if (source == null) {

Resource resource =
new ClassPathResource("org/springframework/beans/factory/xml/support/spring-test.xsd");

source = new InputSource(resource.getInputStream());

source.setPublicId(publicId);

source.setSystemId(systemId);

}

return source;

}

}

关键的一步,如何生效:

String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";

NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(
getClass().getClassLoader(), location);

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

reader.setNamespaceHandlerResolver(resolver);

reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);

reader.setEntityResolver(new DummySchemaResolver());

reader.loadBeanDefinitions(getResource());

写一个测试xml文件:

 

http://www.springframework.org/schema/beans/testhttp://www.springframework.org/schema/beans/factory/xml/support/spring-test.xsd">

 

相关的测试方法:

publicvoid testSimpleParser() throws Exception {

TestBean bean = (TestBean) this.beanFactory.getBean("testBean");

assetTestBean(bean);

}

publicvoid testSimpleDecorator() throws Exception {

TestBean bean = (TestBean) this.beanFactory.getBean("customisedTestBean");

assetTestBean(bean);

}

publicvoid testProxyingDecorator() throws Exception {

ITestBean bean = (ITestBean) this.beanFactory.getBean("debuggingTestBean");

assetTestBean(bean);

assertTrue(AopUtils.isAopProxy(bean));

Advisor[] advisors = ((Advised) bean).getAdvisors();

assertEquals("Incorrect number of advisors", 1, advisors.length);

assertEquals("Incorrect advice class.", DebugInterceptor.class, advisors[0].getAdvice().getClass());

}

publicvoid testChainedDecorators() throws Exception {

ITestBean bean = (ITestBean) this.beanFactory.getBean("chainedTestBean");

assetTestBean(bean);

assertTrue(AopUtils.isAopProxy(bean));

Advisor[] advisors = ((Advised) bean).getAdvisors();

assertEquals("Incorrect number of advisors", 2, advisors.length);

assertEquals("Incorrect advice class.", DebugInterceptor.class, advisors[0].getAdvice().getClass());

assertEquals("Incorrect advice class.", NopInterceptor.class, advisors[1].getAdvice().getClass());

}

publicvoid testDecorationViaAttribute() throws Exception {

RootBeanDefinition beanDefinition
= (RootBeanDefinition)this.beanFactory.getBeanDefinition("decorateWithAttribute");

assertEquals("foo", beanDefinition.getAttribute("objectName"));

}

privatevoid assetTestBean(ITestBean bean) {

assertEquals("Invalid name", "Rob Harrop", bean.getName());

assertEquals("Invalid age", 23, bean.getAge());

}

查看本文来源
分享到:
评论

相关推荐

    Spring 2.0 源代码

    通过深入研究Spring 2.0源代码,开发者可以更好地理解其设计思想,优化自己的代码,并能够自定义和扩展Spring的功能,以满足特定项目需求。无论是为了学习、调试还是贡献代码,了解Spring 2.0源代码都将是一个宝贵的...

    spring2.0技术手册_源代码(全十章)

    DI是Spring的核心特性,通过源码,我们可以学习到如何定义bean的配置,如何使用`@Autowired`和`@Qualifier`注解实现自动装配,以及如何自定义bean的生命周期。对于AOP,可以研究`@Aspect`和`@Pointcut`注解,理解切...

    spring2.0中文教程参考文档

    1. Bean管理:Spring 2.0强化了Bean的生命周期管理,支持基于注解的配置(@Component、@Service、@Repository、@Controller),简化了XML配置,使得代码更加简洁。 2.依赖注入(DI):通过@Autowired注解,Spring...

    Spring2.0 API

    Spring 2.0引入了大量的注解,如`@Autowired`、`@Service`、`@Repository`和`@Controller`,使得开发者可以摆脱XML配置,实现更简洁的依赖注入。`@Autowired`自动匹配类型,减少手动装配工作;`@Component`、`@...

    Spring Boot 2.0官方参考文档

    ### Spring Boot 2.0官方参考文档知识点梳理 #### 一、Spring Boot 2.0简介与系统需求 - **Spring Boot**是一个基于Spring框架的全新子项目,它旨在简化新Spring应用的初始搭建以及开发过程。该版本为2.0.0.BUILD-...

    Spring Data JPA 2.0 标准模板

    **Spring Data JPA 2.0 标准模板详解** Spring Data JPA 是 Spring 框架的一个子项目,它简化了数据访问层的开发,提供了对 Java Persistence API(JPA)的高度抽象和自动化。在 Spring Data JPA 2.0 版本中,它...

    Spring教材

    Spring 2.0增强了XML配置的扩展性,允许用户自定义命名空间和元素,方便构建自己的配置元数据。 - **Annotation驱动配置** Spring 2.0引入了注解支持,如`@Component`、`@Service`、`@Repository`和`@Controller...

    jsp+xml的一个小demo

    XML文档可以包含自定义的标签来描述数据,这使得XML成为跨平台和应用程序间数据交换的理想选择。 【JSP与XML的结合】 1. **JSP中的XML处理** JSP可以通过使用JSP动作元素(JSP Actions)如`<jsp:include>`、`...

    Spring和openJPA集成

    6. **事务管理**:Spring 的事务管理能力使得可以在方法级别控制事务,例如使用 `@Transactional` 注解标记需要事务的方法。 7. **测试**:编写测试用例验证集成是否正确,确保数据持久化和事务管理等功能正常工作...

    spring3.0依赖注入详解

    除了内置的注解,Spring还支持自定义注解,只需在自定义注解上添加`@Component`注解,即可赋予其标记Bean的能力。虽然这一特性不常用,但它展示了Spring的高度灵活性。 ##### BeanNameGenerator与自定义命名策略 ...

    pager-taglib-2.0.rar

    3. **兼容性好**:"pager-taglib-2.0" 兼容各种主流的Web框架,如Spring MVC、Struts等,可以无缝集成到现有的项目结构中。 4. **智能分页**:它能根据数据库记录总数自动计算出页码,并支持跳转至任意页的功能,还...

    springsecurity

    Spring Security的前身是Acegi Security,在Spring 2.0发布时被整合进Spring框架中,并更名为Spring Security。随着版本的迭代,Spring Security不断引入新特性和改进,以适应不断变化的安全需求和技术环境。 #####...

    2021年springboot2.0 入门到精通

    在`pom.xml`中,引入`spring-boot-starter-parent`作为父POM,它提供了依赖管理,确保所有依赖的版本一致。另外,引入`spring-boot-starter-web`,它是SpringBoot的Web核心组件,包含了SpringMVC和其他必要的Web开发...

    UrlRewriter Java v2.0 RC1

    4. **自定义标记**:扩展系统,创建自定义的重写标记,以满足特定的应用场景需求。 5. **与Web框架集成**:与Spring MVC、Struts、JSF等常见Java Web框架兼容,方便集成。 6. **性能优化**:设计上考虑了性能,...

    spring annotation 入门

    Spring 框架自2.0 版本起引入了一系列注解支持,这极大简化了配置管理,并为开发提供了更为简洁灵活的方式。通过注解,可以将业务逻辑与配置分离,减少XML配置文件的编写工作,提高开发效率。 #### 二、核心注解...

    springboot备课.doc

    - **自动配置**:开箱即用,对Spring进行大量预设配置,但同时也允许自定义配置。 - **生产就绪**:包括性能监控、健康检查、外部配置等功能。 - **无XML配置**:强调Java配置,避免XML配置文件。 【Java配置...

    springBoot2.0+mybatis支持多数据源+shiro

    **SpringBoot 2.0**:这是Spring框架的一个子项目,旨在简化Spring应用的初始搭建以及开发过程。它预配置了许多常见的设置,如服务器、数据库、MVC、安全等,使得开发者能够快速上手并专注于业务逻辑。SpringBoot ...

    jsp2_0技术手册

    1. **页面元素**:JSP页面由HTML或XML标记和JSP元素组成,包括指令、脚本元素和动作元素。例如,`<jsp:include>`用于在页面中插入其他文件,`<jsp:useBean>`用于实例化JavaBean。 2. **指令**:如`<%@ page %>`, `...

    activiti所需的包

    - `activiti-engine.jar`:这是Activiti的核心,包含流程引擎,用于解析流程定义(BPMN 2.0 XML文件),执行流程实例,并处理所有与流程相关的任务。 - `activiti-common-db.jar`:提供数据库连接和事务管理的支持...

Global site tag (gtag.js) - Google Analytics