spring自定义标签

【Spring】IOC核心源码学习(三):bean标签和自定义标签实现原理

 

基于schema的spring xml namespace扩展

 

基于Spring可扩展Schema提供自定义配置,扩展XML配置大致需要一下几个步骤: 

1、创建一个需要扩展的组件 

2、定义一个xsd文件描述组件内容 

3、实现BeanDefinitionParser接口,用来解析xsd文件中的定义和组件定义 

4、扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器 

5、编写spring.handlers和spring.schemas文件

<!--EndFragment-->

 

基于Spring可扩展Schema提供自定义配置

扩展XML配置大致需要一下几个步骤, 并将产生的文件打成jar包, 在项目中引用该jar包: 
1、创建一个需要扩展的组件 
2、定义一个xsd文件描述组件内容 
3、实现BeanDefinitionParser接口,用来解析xsd文件中的定义和组件定义 
4、扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器 
5、编写spring.handlers和spring.schemas文件

 

 注意:spring.handlers和spring.schemas文件, 还有mytag.xsd文件都要放到resources文件夹下, 因为使用maven打包, 所在静态文件必须放在这个文件夹下, 就因为这个问题, 我浪费了一下午的时间, 总是提示找不到mytag.xsd文件

 

 源码大概执行过程:

 

1、判断标签的命名空间, 是否是默认的命名空间http://www.springframework.org/schema/beans

 

2、不是默认的命名空间, 则使用自定义标签转换器转换

BeanDefinitionParserDelegate.parseCustomElement(ele)

 

3、

String namespaceUri = ele.getNamespaceURI();   通过元素获取命名空间

 

//取得命名空间解析器DefaultNamespaceHandlerResolver, 找到解析命名空间为namespaceUri的解析器

//取得

NamesresolvepaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); 

 

if (handler == null) {

error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);

return null;

}

return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

 

 

4、加载包下的META-INF/spring.handlers:DefaultNamespaceHandlerResolver.getHandlerMappings()

 

 

public static Properties loadAllProperties(String resourceName, ClassLoader classLoader) throws IOException {

Assert.notNull(resourceName, "Resource name must not be null");

ClassLoader clToUse = classLoader;

if (clToUse == null) {

clToUse = ClassUtils.getDefaultClassLoader();

}

Properties properties = new Properties();

Enumeration urls = clToUse.getResources(resourceName);

while (urls.hasMoreElements()) {

URL url = (URL) urls.nextElement();

InputStream is = null;

try {

URLConnection con = url.openConnection();

con.setUseCaches(false);

is = con.getInputStream();

properties.load(is);

}

finally {

if (is != null) {

is.close();

}

}

}

return properties;

}

 

5、从META-INF/spring.handlers中获取对应命名空间的处理类

http\://www.360buy.com/schema/ice=com.jd.common.ice.IceNamespaceHandler

 

6、加载处理类, 并实例化, 执行处理类的init方法,

NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);

namespaceHandler.init();

handlerMappings.put(namespaceUri, namespaceHandler);

 

 

7、执行处理类的init方法, 将自定义标签解析器注册到NamespaceHandlerSupport.parsers(Map)的属性中

 

registerBeanDefinitionParser("config", new IceProxyBeanDefinitionParser());

 

8、执行NamespaceHandlerSupport.parse()方法, 从NamespaceHandlerSupport.parsers的属性中, 找到对应的解析器,执行parse()方法,最终返回BeanDefinition对象, 

在parse()方法中, 重要的是:

 def.setBeanClass(TagOne.class);  在这里指定生成Bean对象对应的Class

 

 

9、何时执行getObject()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值