为什么80%的码农都做不了架构师?>>>   

Spring源码-context:component-scan的解析过程

上次已经讲过 Spring源码-applicationcontent.xml解析过程 ,先回顾一下,上次讲了applicationcontext.xml 是如何解析的,主要流程其实就是获取applicationcontent.xml输入流=》解析成Doc=》根据子节点(标签)的属性判断是自定义还是默认的标签=》根据标签的类别进行解析=》调用解析类进行解析。上篇文章没有着重讲到针对applicationcontent.xml中的标签是通过什么方式来解析的?及其解析流程是什么样的?所以在这里我将从Spring中比较重要的标签<context:component-scan base-package=""/> 入手,讲一讲这个标签的解析类是怎么去解析的。

1. 先贴出本次标签配置已经对应的标签的解析类

标签配置:

<!-- annotation-config="true" 这是默认值,所以可以省略  -->
<context:component-scan base-package="cn.edu.his.pay cn.edu.his.pay2" annotation-config="true"><!-- 排除@Controller的注解  --><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

标签的解析类:

ComponentScanBeanDefinitionParser#parse

2. 再贴出核心流程总结图

3. 如上已经对整个核心流程有一定的了解,那现在我们就针对开发中能遇到的一些问题进行源码层面的分析

1)如何配置多个包扫描路径?

正常我们都是用“,”来配置多个包扫描路径的,配置如下:

<context:component-scan base-package="cn.edu.his.pay,cn.edu.his.pay2">
</context:component-scan>

但你阅读完源码后其实你会发现配置方式不止这一种,其实在根据base-package配置信息,使用到了StringTokenizer分割字符串,分割的规则是“,; \t\n”,如下是演示分割的代码:

package cn.edu.his.pay.controller.test;import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;public class Main {public static void main(String[] args) {StringTokenizer st = new StringTokenizer("cn.edu.his.pay cn.edu.his.pay2", ",; \t\n");List<String> tokens = new ArrayList<>();while (st.hasMoreTokens()) {String token = st.nextToken();if (true) {token = token.trim();}if (!true || token.length() > 0) {tokens.add(token);}}System.out.println(tokens); //得到分割后的集合为 [cn.edu.his.pay, cn.edu.his.pay2]}}

其实可以得出,配置多路径扫描也可以用“,”、空格、“;”、“,;”来配置,扫描包得到的是一样的。

2)配置了context:component-scan标签后还需要配置context:annotation-config标签吗?

其实不用,因为context:component-scan标签中就对应context:annotation-config配置进行支持了,可以通过如下配置完成支持,其实这个annotation-config的属性还可以不设置,默认为true。

<!-- 不需要这样再配置了 -->
<!-- <context:annotation-config /> -->
<context:component-scan base-package="cn.edu.his.pay,cn.edu.his.pay2" annotation-config="true">
</context:component-scan>

如下是相关部分源代码:

// 如有必要,注册注释配置处理器。
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) {Set<BeanDefinitionHolder> processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}
}

3)配置了use-default-filters到底有什么用?

use-default-filters的配置方式如下,不配置默认该属性为true,默认会将@Component过滤器的注册。

<context:component-scan base-package="cn.edu.his.pay,cn.edu.his.pay2" use-default-filters="true">
</context:component-scan>

这里配置use-default-filters=true其实就是让Spring过滤的时候将代码有@Component和@Component子注解的Class封装到BeanDefinition中。

4)那哪些是@Component的子注解了?

其实只要是注解上带有@Component的注解都是@Component的子注解。

5)我们经常在context:component-scan标签中定义子标签context:exclude-filter和context:include-filter 这又有什么用了?

其实这二个标签的用处还是挺多的,一般我们在配置配置文件的时候,都喜欢进行分层配置,比如:service的用一个my-service.xml,而mvc的我们用一个my-mvc.xml来单独配置,这个时候这二个标签就能用着了。这二个配置文件下都需要配置包扫描context:component-scan,所以这里为了避免重复扫描,可能会采用如下方式来配置:

my-service.xml

<context:component-scan base-package="cn.edu.his.pay"><!-- 排除@Controller的注解  --><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

my-mvc.xml

<context:component-scan base-package="cn.edu.his.pay"><!-- 排除@Service的注解  --><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>

简单的理解就是:context:exclude-filter(将包下带有指定类型指定注解的类进行过滤掉,不注册成BeanDefinition),context:include-filter(将包下带有指定类型指定注解的类进行注册成BeanDefinition),所以我们经常为了避免重复的去注册BeanDefinition而配置指定的过滤规则。

转载于:https://my.oschina.net/qrmc/blog/1811025

Spring源码-context:component-scan的解析过程相关推荐

  1. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  2. spring 源码分析(1)-xml文件解析

    我们在最开始接触spring的时候,看到不少书spring入门的例子如下 ApplicationContext atx = new ClassPathXmlApplicationContext(&qu ...

  3. spring源码分析06-spring配置类解析

    什么是spring配置类? 类上有注解:@Configuration .@Component.@ComponentScan.@Import.@ImportResource 或者类中的任意方法有@Bea ...

  4. spring 源码-context

    1 spring-context 模块概要 该模块主要实现在spring-beans 模块的扩展,主要对aop支持及el表达式的实现 分析示例 public static void main(Stri ...

  5. 【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)

    [Spring源码系列- IOC] 1 [Spring源码]0.安装Gradle环境 2 [Spring源码]1.下载与编译_pom relocation to an other version nu ...

  6. Spring 源码第三弹!EntityResolver 是个什么鬼?

    上篇文章和小伙伴们说了 Spring 源码中 XML 文件的解析流程,本来可以继续往下走看加载核心类了,但是松哥还是希望能够慢一点,既然要学就学懂,在 XML 文件解析的过程中还涉及到一些其他的类和概 ...

  7. Mac系统Spring源码导入

    Mac系统Spring源码导入 前言 工具准备 Gradle5.6.4安装 Spring-Framework5.2.8 Kotlin插件 spring-framework配置 修改settings.g ...

  8. Spring源码解析之@Component注解的扫描

    阅读须知 Spring源码版本:4.3.8 文章中使用/* */注释的方法会做深入分析 正文 承接Spring源码解析之context:component-scan标签解析,下面就是扫描的流程: Cl ...

  9. Spring源码学习(三)-- 底层架构核心概念解析

    前面,我们大概了解了Spring中的一些概念和底层工作流程,这篇是后续看Spring源码所必备的,防止后续看源码的过程中,遇到不会的概念得单独跳出来学习.​ BeanDefinition BeanDe ...

  10. Spring源码分析(二):底层架构核心概念解析

    本节主要介绍一下Spring底层中用到的"基础设施",是后续看Spring源码所必备的,防止后续看源码的过程中,遇到不会的概念得单独跳出来学习. BeanDefinition Be ...

最新文章

  1. 14 Java面试之 IO 流技术
  2. 关于5G,看这一篇文章就够了
  3. 无法从“const char [10]”转换为“char *”
  4. error_reporting笔记
  5. WCF 第六章 序列化和编码之DataContractJsonSerializer
  6. linux进程管理类命令大全,Linux进程管理类命令
  7. 人工智能目标检测模型(四)——ResNet
  8. 遗传算法的原理与python实现
  9. WF4读书笔记(一):创建一个简单的工作流
  10. 教之初在线计算机考题,教之初计算机考试系统出题说明.pdf
  11. 用MATLAB 读写各种文件 ∈ Matlab 使用笔记
  12. 2009国内免费网盘横向评测
  13. 百度网盘链接怎么同步更新、百度网盘链接同步、百度网盘分享同步更新、百度网盘怎么同步更新、百度网盘资源同步更新、百度网盘分享文件同步更新、百度网盘好友分享同步更新、百度网盘共享文件同步更新...
  14. Ubuntu20.04无法连接wifi的解决方法
  15. mysql中Tinyint(1)和Tinyint(4)的区别
  16. (U8)系统管理登录时提示“缺少根元素”
  17. EulerOS 2.0 SP5 - 华为欧拉(CentOS 7 华为版)下载
  18. [VBA]EXCEL同工作簿中多工作表合并VBA代码
  19. LCA(包含RMQ)
  20. Python资源大全中文版

热门文章

  1. Atitit java wav 压缩 mp3功能总结 目录 1.1. Lame mp3编码器 1 1.2. 使用时发现错误,不支持Unsupported number of channels: 4
  2. atitit.数据验证--db数据库数据验证约束
  3. atitit.提升研发效率的利器---重型框架与类库的区别与设计原则
  4. Paip.YXSHOP易想商场功能模块说明
  5. Julia:1.0与0.6 的几点不同
  6. 从原子操作走向模板部署,详解云上资源自动化部署新模式
  7. 2018中国十大开源云领军企业评选,等你报名!
  8. android 打包成多个so,Android Studio打包.so库到apk中实例详解
  9. 【数据预测】基于matlab LSTM神经网络空调能耗数据预测【含Matlab源码 051期】
  10. 【语音隐写】基于matlab GUI LSB语音信号数字水印嵌入提取(带面板)【含Matlab源码 1676期】