【Spring之ComponentScanAnnotationParser】

ComponentScanAnnotationParser

  • 1. ComponentScanAnnotationParser属性解析
  • 2. 一个重要方法---parse

1. ComponentScanAnnotationParser属性解析

	private final Environment environment;// 用于获取当前应用运行时的配置信息,包括但不限于系统属性、环境变量以及通过PropertySource添加// 的各种属性源。在处理@ComponentScan时,可能需要根据环境来决定哪些包或类应该被扫描。private final ResourceLoader resourceLoader;// spring资源加载器,用于加载不同类型的资源(如文件、类路径资源等)。在执行组件扫描时,可能需要// 加载指定包下面的所有类,这就需要用到ResourceLoader。private final BeanNameGenerator beanNameGenerator;// 一个策略接口实现,用于生成那些未明确提供名称的bean的默认名称。在扫描并创建bean的过程中,如//果没有未某个@Component或者@Service等注解的类显式设置beanName,则会用到此接口来生成唯一且有意	// 义的bean名称。private final BeanDefinitionRegistry registry;// SpringIOC容器的核心组件之一,它是所有BeanDefinition的注册表。ComponentScanAnnotationParser在// 解析过程中发现符合组件条件的类后,会将对应的BeanDefinition注册到这个BeanDefinitionRegistry中,// 使得这些类实例化后可以作为spring容器管理的bean进行依赖注入和生命周期管理。

2. 一个重要方法—parse

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {// 创建类路径bean定义扫描ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);// 获取nameGeneratorClass<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :BeanUtils.instantiateClass(generatorClass));ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");if (scopedProxyMode != ScopedProxyMode.DEFAULT) {scanner.setScopedProxyMode(scopedProxyMode);}else {// 获取scope解决器Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");// 设置scope解决器scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));}// 设置资源模式scanner.setResourcePattern(componentScan.getString("resourcePattern"));// 添加用户自定义的incluedeFilterfor (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter : typeFilters) {scanner.addIncludeFilter(typeFilter);}}// 添加用户自定义的excludeFilterfor (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,this.resourceLoader, this.registry);for (TypeFilter typeFilter : typeFilters) {scanner.addExcludeFilter(typeFilter);}}// 设置懒initboolean lazyInit = componentScan.getBoolean("lazyInit");if (lazyInit) {scanner.getBeanDefinitionDefaults().setLazyInit(true);}Set<String> basePackages = new LinkedHashSet<>();// 获取basePackagesString[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg : basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}// 如果为空, 则指定当前的配置类为基础包if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}// 为了确保声明了@ComponentScan注解的类自身不会被扫描并注册为Bean。因为在大多数情况下,// 我们并不希望扫描器将包含@ComponentScan注解的类当作一个组件来处理。scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});// 调用ClassPathBeanDefinitionScanner#doScan方法,返回Set<BeanDefinitionHolder>return scanner.doScan(StringUtils.toStringArray(basePackages));}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL基础学习: 使用EXPLAIN查看执行计划详解分析

一、EXPLAIN语句的作用 在客户端执行MySQL的操作语句&#xff0c;会依次经过MySQL客户端连接管理、语法解析与优化&#xff08;查询缓存、语法解析、查询优化&#xff09;、存储引擎层。其中查询优化器在基于成本和规则对查询语句进行优化&#xff0c;并且在优化后会生成一个执…

Redis学习指南(6)-Redis的数据类型简介

文章目录 引言1. 字符串 (String)2. 哈希 (Hash)3. 列表 (List)4. 集合 (Set)5. 有序集合 (ZSet)结语 引言 Redis是一种高性能的键值存储系统&#xff0c;被广泛应用于缓存、消息队列等场景。其中&#xff0c;Redis的数据类型是其强大功能的基础之一。本文将深入介绍Redis的主…

nacos配置中心只能获取部分配置的问题

检查配置中心&#xff0c;在配置中心里是可以看到监听的服务地址的&#xff0c;但是却获取不到配置 nacos配置中心主要是在这个NacosConfigService的这个类下面。该接口下面主要有一些获取配置&#xff0c;发布配置&#xff0c;增加监听器&#xff0c;删除配置&#xff0c;删…

一个简易的PHP论坛系统

一个简易的PHP论坛系统 php课程设计&#xff0c;毕业设计 预览 技术 bootstrap 4.x jquery css php mysql 5.7 目录结构 登录 管理员 admin/123456 测试用户 user1/123456 更多文章和源码获取查看

Windows平台RTMP推送|轻量级RTSP服务录像模块如何支持中文路径?

技术背景 我们在做Windows平台RTMP推送、轻量级RTSP服务录像模块的时候&#xff0c;部分开发者抱怨路径无法设置中文&#xff0c;只能设置为英文。 以C#的接口为例&#xff0c;早期的设计如下&#xff1a; /** 设置本地录像目录, 必须是英文目录&#xff0c;否则会失败*/[DllI…

Debezium发布历史66

原文地址&#xff1a; https://debezium.io/blog/2019/07/25/debezium-0-10-0-beta3-released/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 0.10.0.Beta3 发布 七月 25, 2019 作者&#xff1a; Jir…

【PostgreSQL】数据查询-LIMIT AND OFFSET

PostgreSQL数据查询-LIMIT AND OFFSET PostgreSQL中LIMIT并允许您仅检索由查询的其余部分生成的部分行&#xff1a;OFFSET SELECT select_listFROM table_expression[ ORDER BY ... ][ LIMIT { number | ALL } ] [ OFFSET number ]如果给出了限制计数&#xff0c;则返回的行数…

【Java SE语法篇】8.面向对象三大特征——封装、继承和多态

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1. 封装1.1 封装的概念1.2 为什么封装1.3 封装的实现…

Leetcode with Golang 滑动窗口 Part1

滑动窗口的定义&#xff1a; 滑动窗口这一个技巧主要运用于处理数组问题上&#xff0c;一般用于“子串”问题。精髓是&#xff0c;维护一个里面装着元素的“窗口”&#xff0c;在将新元素装进“窗口”的同时&#xff0c;根据题意&#xff0c;把不符合题意的元素踢出“窗口”。…

漏洞复现-nginxWebUI runCmd前台远程命令执行漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

Pandas实战100例 | 案例 33: 使用 `loc` 和 `iloc` 选择数据

案例 33: 使用 loc 和 iloc 选择数据 知识点讲解 在 Pandas 中&#xff0c;loc 和 iloc 是两种主要的数据选择方法。loc 是基于标签的选择方法&#xff0c;而 iloc 是基于整数位置的选择方法。 loc: 使用行标签和列名来选择数据。iloc: 使用行和列的整数位置&#xff08;从 …

1222. 密码脱落(dp划分)

题目&#xff1a; 1222. 密码脱落 - AcWing题库 思路&#xff1a; 代码&#xff1a; #include<cstdio> #include<cstring> using namespace std; const int N1010; int f[N][N];//表示以L和R为两端点的字符串的“最长”回文序列长度 char s[N];//存储输入的字符串…

buuctf-Misc 题目解答分解115-117

115.派大星的烦恼 解压下载文件时一个 bmp 文件&#xff0c;用notepad 打开有没有发现什么 &#xff0c;提示位图什么的 用Stegsolve.jar 打开 发现很多. 和- 第一时间想到了 电报码 但提示不是电报码&#xff0c;除了这个那就是很像二进制了 0,1 什么的&#xff0c;但这个感觉…

Sqoop与其他数据采集工具的比较分析

比较Sqoop与其他数据采集工具是一个重要的话题&#xff0c;因为不同的工具在不同的情况下可能更适合。在本博客文章中&#xff0c;将深入比较Sqoop与其他数据采集工具&#xff0c;提供详细的示例代码和全面的内容&#xff0c;以帮助大家更好地了解它们之间的差异和优劣势。 Sq…

六、新建窗体时,几种窗体的区别

新建窗体时&#xff0c;会有几种类型的选项&#xff0c;很多同学不明白其中的意思&#xff0c;我们在本章节中详细介绍一下几种窗体的区别。 窗体的类型分以下几种 Dialog with Buttons Bottom 带按钮的对话框&#xff0c;按钮在底部 Dialog with Buttons Right 带按钮的对话框…

【计算机组成原理】高速缓冲存储器 Cache 的写策略(Writing Policy)

写策略 Writing Policy 缓存的写策略指的是确定何时将数据写入缓存或主存的策略。 写命中 Write Hit 全写法 Write Through 在全写法策略中&#xff0c;每次发生写操作时都会将数据同时写入缓存和主存。这样可以保证数据的一致性&#xff0c;但会增加主存的写入操作&#xf…

深入 Move 生态,探秘铭文热潮背后的思考

Move 语言是 Meta&#xff08;Facebook&#xff09;在 2018 年开发的新一代智能合约编程语言。回顾过去的一年&#xff0c;Aptos 与 Sui 主网上线&#xff0c;为整个 Web3 开启了下一个十亿用户服务的新征程。Rooch、Initia、MoveMent 等多条使用 Move 语言的区块链网络涌现&am…

1 pytest入门

pytest入门 示例成功失败 1.1 资源获取官方文档安装 1.2 运行 Pytest测试搜索命名规则 1.3 运行单个测试用例1.4 使用命令行选项-h&#xff08;--help&#xff09;--collect-only-k-m-x--maxfailnum-s 与 --capturemethod-s 等价于 --captureno--capturesys--capturefd -l&…

win10重新安装Windows应用商店

安装Windows 终端 用 PowerShell 重装 Microsoft Store使用 MSIX 包重装 Microsoft Store下载安装包及依赖下载Windows 应用商店的安装包安装包是依赖组件包 微软应用商店无法连接网络解决办法 参考&#xff1a; wind10自带的终端程序和powerShell 真是太垃圾了&#xff0c; 突…

python爬虫,发送请求需要携带cookies

此网站&#xff0c;需要先注册登录&#xff01;&#xff01;&#xff01; 页面源代码&#xff1a; <!DOCTYPE html><html lang"zh-Hans"><head><meta charset"UTF-8"><meta http-equiv"x-ua-compatible" content&qu…