五、component-scan 标签的解析原理

本文详细解析了Spring框架中component-scan标签的工作原理,从标签配置到源码解析,包括自定义标签解析机制、ContextNamespaceHandler、ComponentScanBeanDefinitionParser的解析过程,以及注解扫描器如何扫描和注册BeanDefinition。通过对component-scan标签的深入理解,有助于更好地掌握Spring的自动组件扫描功能。

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

一、component-scan概述

1、Spring中component-scan标签配置

spring5.exercise.demo17.spring.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=
       "
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       ">
    <!-- 自定义标签 扫描包 -->
    <context:component-scan base-package="com.jd.nlp.dev.muzi.spring5.exercise.demo17" />
    
</beans>

描述
上述spring.xml配置中,配置了一个component-scan标签,这个标签的作用是扫描项目代码中com.jd.nlp.dev.muzi.spring5.exercise.demo01下的class类,如果有@Service @Controller @Component等注解的类,将这些类解析成一个个的BeanDefinition,容器初始化时会针对这些类去创建实例对象。

2、component-scan功能案例代码

com.jd.nlp.dev.muzi.spring5.exercise.demo17.ProductService

@Service("productService")
public class ProductService {

    private String name = "Muzi";

    private String well = "开始Spring5的炫酷之旅,(Muzi)书生不读四书五经!";

    public void show() {
        System.out.println(name + "\n" + well);
    }

    public ProductService() {
        this.name = "无参数构造函数";
    }
}

测试容器启动代码

    @Test
    public void run01(){
        // 基于加载XML配置文件的方式,启动spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring5.exercise.demo17.spring.xml");
        ProductService productService = (ProductService) context.getBean("productService");
        productService.show();
    }

描述
上述测试代码中,创建了基于解析XML的容器,解析spring5.exercise.demo17.spring.xml配置文件,在配置文件中配置了一个component-scan标签去扫描“com.jd.nlp.dev.muzi.spring5.exercise.demo17”包下面的含有Spring @Component下的类ProductService。
我们测试代码中通过容器获取ProductService的实例,调用show方法。

测试结果

09:54:56.037 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'productService'
无参数构造函数
开始Spring5的炫酷之旅,(Muzi)书生不读四书五经!

那么具体component-scan标签是如何解析的呢?和我跟着源码一点一点阅读吧。

二、component-scan解析源码

1、回顾Spring的自定义标签解析(SPI)

component-scan是一个自定义标签

<context:component-scan base-package="com.jd.nlp.dev.muzi.spring5.exercise.demo17" />

namespace uri是http://www.springframework.org/schema/context

xmlns:context="http://www.springframework.org/schema/context"

所以我们需要去context的jar包去找 spring.handlers文件
spring-context的spring.handlers文件

http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler

基于上述文件可知,http://www.springframework.org/schema/context这个namespace uri对应的解析类是“org.springframework.context.config.ContextNamespaceHandler”

在ContextNamespaceHandler的init方法中,component-scan这个自定义标签是ComponentScanBeanDefinitionParser这个解析类来进行解析的。

	@Override
	public void init() {
		// 标签元素和解析类的映射关系
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionPar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值