Spring中的NamespaceHandler与BeanDefinitionParser详解
1.前文
由Spring启动过程之-obtainFreshBeanFactory()
可以看到NamespaceHandler、BeanDefinitionParser为解析配置文件中的Element起重要作用。
那么它本身是如何被加载的呢?
2.NamespaceHandler之ContextNamespaceHandler
常见的NamespaceHandler实例:ContextNamespaceHandler
很明显能看出有常用的 context:annotation-config/、<context:component-scan base-package=“xx”/>、context:property-placeholder/对应的解析类。

3.BeanDefinitionParser的作用
解析相关节点,并注册BeanDefinition。
3.1 PropertyPlaceholderBeanDefinitionParser
大致流程为解析<context:property-placeholder location="classpath:module.properties" />节点,包装PropertySourcesPlaceholderConfigurer为BeanDefinition,将里面的属性装配到BeanDefinition中,并注册到BeanDefinitionMap。
PropertyPlaceholderBeanDefinitionParser#parse: AbstractBeanDefinitionParser-> parseInternal-> BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();//创建BeanDefinition ... builder.getRawBeanDefinition().setBeanClass(PropertySourcesPlaceholderConfigurer.class); ... doParse(element, parserContext, builder)-> super.doParse(element, parserContext, builder);//解析公共属性:location,fileEncoding等 ....//做特殊属性的解析 return builder.getBeanDefinition(); //统一注册 registerBeanDefinition(holder, parserContext.getRegistry());
3.2 ComponentScanBeanDefinitionParser
解析节点<context:component-scan base-package="com.gkwind"/>本身。并根据其配置,做特殊的class扫描,将符合配置的class,如被@Component标记过的类 包装成BeanDefinition,注入到BeanDefinitionMap中。 注意这里做的工作是根据配置,扫描加载了配置对应的多个类
ComponentScanBeanDefinitionParser#parse流程

NamespaceHandler 加载过程
跟踪源码, 可以发现解析非自定义命名空间parseCustomElement时会调用DefaultNamespaceHandlerResolver#resolve,然后resolve得到的所有NamespaceHandler。之后得到命名空间对应的NamespaceHandler 再NamespaceHandler#init初始化相关的parser。
getHandlerMappings以SPI的方式得到所有spring.handlers

NamespaceHandler 加载流程

作用:可实现自定义标签
知道了NamespaceHandler与BeanDefinitionParser作用后, 我们可以自定义schema,然后在spring的xml中自定义命名空间thewindkee标签<thewindkeetag>,再实现thewindkee对应的NamespaceHandler与<thewindkeetag>的BeanDefinitionParser,最后将NamespaceHandler配置到META-INF/spring.handlers。
大致Java代码:
class TheWindKeeNamespaceHandler extends NamespaceHandlerSupport {
public void init(){
registerBeanDefinitionParser("thewindkeetag", new TheWindKeeTagBeanDefinitionParser());
}
}
class TheWindKeeTagBeanDefinitionParser extends AbstractBeanDefinitionParser{
public final BeanDefinition parse(Element element, ParserContext parserContext) {
//解析element
....
//注册BeanDefinition
registerBeanDefinition(holder, parserContext.getRegistry());
}
}到此这篇关于Spring中的NamespaceHandler与BeanDefinitionParser详解的文章就介绍到这了,更多相关NamespaceHandler与BeanDefinitionParser内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot中集成IP2Region实现高效IP地址地理位置查询
IP2Region是一个高效的IP地址地理位置查询库,能够快速根据IP地址获取其地理位置信息,它支持IPv4和IPv6地址的查询,并提供多种缓存方式来优化查询性能,在这篇博客中,我们将介绍如何将IP2Region集成到SpringBoot项目中,实现IP地址的地理位置查询服务2025-12-12
Java中ClassNotFoundException的类加载问题排查与修复方法
在Java开发中,java.lang.ClassNotFoundException是常见的运行时异常,通常表示JVM在尝试加载某个类时未能找到其定义,本文结合实战经验,系统性分析ClassNotFoundException的排查与修复方法,并提供丰富的代码示例和表格分析,需要的朋友可以参考下2025-06-06


最新评论