Spring源码讲解(一)Spring注册BeanDefinition(解析配置类)

2024-06-11 05:48

本文主要是介绍Spring源码讲解(一)Spring注册BeanDefinition(解析配置类),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由于Spring源码过于庞大,文章中不会列出细节,须要大家花时间下去研究哦

在此之前首先须要理解两个对象:

AnnotatedBeanDefinitionReader

在AnnotationConfigApplicationContext上下文对象实例化时,spring会实例化这两个对象,

AnnotatedBeanDefinitionReader对象顾名思义就是AnnotatedGenericBeanDefinition类型的bd的读取器,调用其register方法注册的bean注册的bd类型就是AnnotatedGenericBeanDefinition。

spring中通过注解启动spring容器时使用的AnnotationConfigApplicationContext上下文对象中会传入一个JAVA-Config类,这个类注册的bd就是AnnotatedGenericBeanDefinition。

我们也可以通过调用AnnotationConfigApplicationContext#register方法将须要的对象注册为bean,当然其bd类型也是AnnotatedGenericBeanDefinition,不过这个无所谓。

 

ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner对象顾名思义就是类路径下的bd扫描器,可以通过传入一个包路径扫描加了@Component;@Service;等表示一个bean的java文件,并转换成BeanDefinition类型。

我们也可以通过调用AnnotationConfigApplicationContext#scan方法将指定目录下的一些对象注册为bd。

 

解析配置类

spring注册bd主要是依赖的ConfigurationClassPostProcessor这个类,他是spring中最最重要的一个类,实现了BeanDefinitionRegistryPostProcessor接口,这个接口又继承自BeanFactoryPostProcessor,所以这个类在spring初始化注册bd时发挥着重要的作用。

spring会在初始化AnnotatedBeanDefinitionReader对象时顺带着将其注册为bd,看下这个AnnotationConfigUtils#registerAnnotationConfigProcessors方法:

当然这里还会注册其他的几个bd,都是spring初始化时须要用到的几个关键类,这里先注册,后面使用会根据bd来构建出这个bean。

之后,执行AnnotationConfigApplicationContext#refresh方法 ->

AnnotationConfigApplicationContext#invokeBeanFactoryPostProcessors方法 ->

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法

很明显,上面的方法顾名思义就是用来执行BeanFactoryPostProcessor的(BeanDefinitionRegistryPostProcessor也算是BeanFactoryPostProcessor)

invokeBeanFactoryPostProcessors方法中的执行顺序是这样的:

1.自定义(手动add进来的)BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

2.spring容器中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

3.spring容器中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

4.spring容器中其他(实现了PriorityOrdered和Ordered之外的)BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

5.所有(包括自定义的和由spring管理的)BeanDefinitionRegistryPostProcessor的父类BeanFactoryPostProcessor的postProcessBeanFactory方法

6.所有自定义的BeanFactoryPostProcessor的postProcessBeanFactory方法

7.所有spring管理的BeanFactoryPostProcessor(实现了PriorityOrdered接口)的postProcessBeanFactory方法

8.所有spring管理的BeanFactoryPostProcessor(实现了Ordered接口)的postProcessBeanFactory方法

9.所有spring管理的BeanFactoryPostProcessor(实现了PriorityOrdered和Ordered之外的)的postProcessBeanFactory方法

ConfigurationClassPostProcessor就是在第二步(postProcessBeanDefinitionRegistry)和第五步(postProcessBeanFactory)中执行的,Spring注册各种BeanDefinition都是在这里执行的。

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry ->

ConfigurationClassPostProcessor#processConfigBeanDefinitions ->

ConfigurationClassParser#parse

这里获取到的bdNames其实就是上面说的spring自己注册的几个bd,另外就是再加一个我们添加的加了@Configuration注解的那个配置类的bd了。

走到这里,spirng会对bd类型做判断,这里会走第一个,因为我们手动注册的配置类的bd的类型是AnnotatedGenericBeanDefinition,AnnotatedGenericBeanDefinition就是AnnotatedBeanDefinition的子类。

可以看下AnnotationConfigApplicationContext#register方法:

 

继续走:

ConfigurationClassParser#processConfigurationClass ->

ConfigurationClassParser#doProcessConfigurationClass

就是在这里解析配置类的各种注解的(@ComponentScans;@ComponentScan;@Import;@Bean)

这篇关于Spring源码讲解(一)Spring注册BeanDefinition(解析配置类)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050351

相关文章

SpringBoot结合Knife4j进行API分组授权管理配置详解

《SpringBoot结合Knife4j进行API分组授权管理配置详解》在现代的微服务架构中,API文档和授权管理是不可或缺的一部分,本文将介绍如何在SpringBoot应用中集成Knife4j,并进... 目录环境准备配置 Swagger配置 Swagger OpenAPI自定义 Swagger UI 底

解决hive启动时java.net.ConnectException:拒绝连接的问题

《解决hive启动时java.net.ConnectException:拒绝连接的问题》Hadoop集群连接被拒,需检查集群是否启动、关闭防火墙/SELinux、确认安全模式退出,若问题仍存,查看日志... 目录错误发生原因解决方式1.关闭防火墙2.关闭selinux3.启动集群4.检查集群是否正常启动5.

SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南

《SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南》本文将基于开源项目springboot-easyexcel-batch进行解析与扩展,手把手教大家如何在SpringBo... 目录项目结构概览核心依赖百万级导出实战场景核心代码效果百万级导入实战场景监听器和Service(核心

idea Maven Springboot多模块项目打包时90%的问题及解决方案

《ideaMavenSpringboot多模块项目打包时90%的问题及解决方案》:本文主要介绍ideaMavenSpringboot多模块项目打包时90%的问题及解决方案,具有很好的参考价值,... 目录1. 前言2. 问题3. 解决办法4. jar 包冲突总结1. 前言之所以写这篇文章是因为在使用Mav

Spring Security6.3.x的使用指南与注意事项

《SpringSecurity6.3.x的使用指南与注意事项》SpringSecurity6.3.1基于现代化架构,提供简洁配置、增强默认安全性和OAuth2.1/OIDC支持,采用Lambda... 目录介绍基础配置 (Servlet 应用 - 使用 Lambda DSL)关键配置详解(Lambda DS

Java Stream 的 Collectors.toMap高级应用与最佳实践

《JavaStream的Collectors.toMap高级应用与最佳实践》文章讲解JavaStreamAPI中Collectors.toMap的使用,涵盖基础语法、键冲突处理、自定义Map... 目录一、基础用法回顾二、处理键冲突三、自定义 Map 实现类型四、处理 null 值五、复杂值类型转换六、处理

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

Oracle迁移PostgreSQL隐式类型转换配置指南

《Oracle迁移PostgreSQL隐式类型转换配置指南》Oracle迁移PostgreSQL时因类型差异易引发错误,需通过显式/隐式类型转换、转换关系管理及冲突处理解决,并配合验证测试确保数据一致... 目录一、问题背景二、解决方案1. 显式类型转换2. 隐式转换配置三、维护操作1. 转换关系管理2.

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

IDEA中配置Tomcat全过程

《IDEA中配置Tomcat全过程》文章介绍了在IDEA中配置Tomcat的六步流程,包括添加服务器、配置部署选项、设置应用服务器及启动,并提及Maven依赖可能因约定大于配置导致问题,需检查依赖版本... 目录第一步第二步第三步第四步第五步第六步总结第一步选择这个方框第二步选择+号,找到Tomca