component-scan标签解析

本文深入剖析了Spring中`<context:component-scan>`标签的解析过程,包括解析前的准备工作,如注册标签解析器;扫描器的创建,如`ComponentScanBeanDefinitionParser`的`parse`方法及`ClassPathBeanDefinitionScanner`的构造和配置;扫描器的扫描,涉及类路径的遍历和注解过滤;以及扫描器的运用,通过自定义扫描器实例化。整个过程展示了Spring如何发现和注册带有注解的Bean定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上篇博客中,介绍了对于自定义标签的解析,以及自己实现了一个标签供spring扫描,此篇博客会主要分析下component-scan 标签的解析过程中做了哪些事情.

解析前的准备

首先在xml文件的beans标签中引入context标签
在这里插入图片描述

 <context:component-scan base-package="com"></context:component-scan>

在xml文件中加入上面的代码 base-package指的是扫描的包名
当spring启动后,解析到该段时,是会进入到自定义标签的解析的.

public class ContextNamespaceHandler extends NamespaceHandlerSupport {
   
	@Override
	public void init() {
   
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}
}

context所对应的handler会注册上述的八个标签,其中当使用的是component-scan时,ComponentScanBeanDefinitionParser会负责去解析该标签

ComponentScanBeanDefinitionParser的 parse(Element element, ParserContext parserContext)方法

	public BeanDefinition parse(Element element, ParserContext parserContext) {
   
		//BASE_PACKAGE_ATTRIBUTE就是base-package,获取base-package的值
		String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
		//这里貌似是对路径进行解析,可以支持"${}"这种写法,从Enviroment中获取resources注入进去
		// <context:component-scan base-package="${LOCALAPPDATA}"></context:component-scan>这种配置下
		//${LOCALAPPDATA}被正常解析了,主要还是要Enviroment中得propertySources拥有,应该都可以在此注入
		basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
		//如果是多个包名,会在此被分析出来
		String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

		// 主角在此,获取一个 配置好的ClassPathBeanDefinitionScanner 对象
		ClassPathBeanDefiniti
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值