Spring底层架构源码解析(二)

news2025/1/21 11:35:14

目录

BeanDefiniton

BeanDefinitionReader(读取器)

AnnotatedBeanDefinitionReader

XmlBeanDefinitionReader

ClassPathBeanDefinitionScanner (扫描器)

BeanFactory


有关该篇内容的前置知识可以参考我上篇文章:spring底层源码脉络解析

有关手写简单的实现spring的代码可以参考我的个人仓库:gitee仓库代码

BeanDefiniton

BeanDefiniton是spring源码中比较一个重要的接口,该接口描述了Bena的基本属性,该BeanDefiniton继承了AttributeAccessor, BeanMetadataElement接口,BeanDefiniton也有很多的方法可供实现,以下为其中方法的一部分截图:

其中BeanDefiniton有很多的属性可以值得我们去了解的

class,表示Bean类型
 

scope,表示Bean作用域,单例或原型等

lazyInit:表示Bean是否是懒加载

initMethodName:表示Bean初始化时要执行的方法

destroyMethodName:表示Bean销毁时要执行的方法

 在spring中,我们创建一个Bean时有两类方式(声明式方式,编程类方式),而在声明式方式中又有以下几种方式:

1.使用xml方式:<bean/>

2.使用注解方式@Bean,@Component(@Service,@Controller)

在编程式方式中就可以使用到BeanDefinition 

public class Test {

	public static void main(String[] args) {

		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        // 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中 
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(User.class);
		applicationContext.registerBeanDefinition("User",beanDefinition);

		System.out.println(applicationContext.getBean("User"));
  }
}

我们说了BenaDefinition可以定义Bean的属性值

        //设置作用域
		beanDefinition.setScope("prototype");
		//设置懒加载
		beanDefinition.setLazyInit(true);
		//设置初始方法
		beanDefinition.setInitMethodName("Init");

不管是声明式还是编程式定义的Bean最终都会被spring解析为BeanDefiniton对象,然后被spring所管理

BeanDefinitionReader(读取器)

AnnotatedBeanDefinitionReader

可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,但是解析注解也是有范围的它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、 @Role、@Description

AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(AppConfig.class); 
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new 
AnnotatedBeanDefinitionReader(context); 
// 将User.class解析为BeanDefinition 
annotatedBeanDefinitionReader.register(User.class); 
System.out.println(context.getBean("user")); 

XmlBeanDefinitionReader

可以解析<bean/>标签

AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(AppConfig.class); 
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context); 
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml"); 
System.out.println(context.getBean("user")); 

ClassPathBeanDefinitionScanner (扫描器)

ClassPathBeanDefinitionScanner为扫描器,与BeanDefinitionReader十分相似,它的作用是扫描某个包的路径,然后去解析该类上是否加了@Component注解,然后解析为BeanDefiniton对象

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
context.refresh(); 
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); 
scanner.scan("com.lcyy"); 
System.out.println(context.getBean("userService")); 

BeanFactory

BeanFactory顾名思义为定义Bean的工厂,当我们使用ApplicationContext时,追踪源码可以发现ApplicationContext继承了ListableBeanFactory 和HierarchicalBeanFactory,ListableBeanFactory和HierarchicalBeanFactory都继承至 BeanFactory,所以我们可以认为ApplicationContext继承了BeanFactory。

ApplicationContext也是BeanFactory的一种,拥有BeanFactory支持的所有功 能,不过ApplicationContext比BeanFactory更加强大,ApplicationContext还基础了其他接口,也 就表示ApplicationContext还拥有其他功能,比如MessageSource表示国际化,ApplicationEventPublisher表示事件发布,EnvironmentCapable表示获取环境变量,等等。

在Spring的源码实现中,当我们new一个ApplicationContext时,其底层会new一个BeanFactory出 来,当使用ApplicationContext的某些方法时,比如getBean(),底层调用的是BeanFactory的 getBean()方法。 

在spring的源码中,有一个叫做DefaultListableBeanFactory的实现类,DefaultListableBeanFactory有很多很实用的功能,并且DefaultListableBeanFactory继承了很多接口,在idea的继承图如下:

1. AliasRegistry:支持别名功能,一个名字可以对应多个别名

2. BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition

3. BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象

4. SingletonBeanRegistry:可以直接注册、获取某个单例Bean

5. SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能

6. ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有 BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类 型获取{类型:对应的Bean}的映射关系

7. HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能

8. DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直 接注册、获取某个单例Bean的功能

9. ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上, 添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置 Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示 该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持 Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能

10. FactoryBeanRegistrySupport:支持了FactoryBean的功能

11. AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持 在创建Bean的过程中能对Bean进行自动装配

12. AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了 FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和 获取beanNames

13. ConfigurableListableBeanFactory:继承了ListableBeanFactory、 AutowireCapableBeanFactory、ConfigurableBeanFactory

14. AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了 AutowireCapableBeanFactory,拥有了自动装配的功能

15. DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了 ConfigurableListableBeanFactory接口和B

有关spring的源码部分解析下一篇文章会继续详细说明的。

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

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

相关文章

2024最新-基于 VUE + Flask全国空气质量预测数据可视化

目录 1.1. 项目介绍 1.2. 技术栈 1.3. 数据来源 1.3.1. 设置城市和时间为爬虫程序的入口 1.3.2. 爬虫程序主要代码 1.3.3. 后端代码调用js 1.4. 后端实现 1.5. 前端实现 1.6. 页面展示 1.6.1. 地图展示 1.6.1.1 省级地图 1.6.1.2 县级地图 1.6.2. 全国分布 1.6.3. 区…

项目生命周期的类型

‌项目生命周期的类型包括预测型生命周期、迭代型生命周期、增量型生命周期、适应型生命周期和混合型生命周期。 预测型生命周期&#xff08;或称为瀑布型生命周期&#xff09; 从名称中我们就可以看出&#xff0c;我们对行业和项目是非常了解的&#xff0c;可以预测到下一步…

Laravel邮件发送:从配置到发邮件的指南!

Laravel邮件发送功能如何实现&#xff1f;怎么使用Laravel发信&#xff1f; Laravel作为一款流行的PHP框架&#xff0c;提供了强大且易用的邮件发送功能。AokSend将详细介绍如何从配置到实际发送邮件的全过程&#xff0c;帮助你快速掌握Laravel邮件发送的技巧。 Laravel邮件发…

解决CodeBlocks中的界面wxSmith界面无法打开问题?

在CodeBlocks中&#xff0c;wxSmith如果想要保存已经编辑好的UI界面&#xff0c;你需要勾选生成xrc文件才行。 譬如我这里就有好几个wxSmith的界面&#xff0c;由于没有生成xrc文件&#xff0c;导致关闭项目后&#xff0c;再次打开wxs界面&#xff0c;无法正常导入了&#xff0…

QT开发:事件循环与处理机制的概念和流程概括性总结

事件循环与处理机制的概念和流程 Qt 事件循环和事件处理机制是 Qt 框架的核心&#xff0c;负责管理和分发各种事件&#xff08;用户交互、定时器事件、网络事件等&#xff09;。以下是详细透彻的概念解释和流程讲解。 1. 事件循环&#xff08;Event Loop&#xff09;的概念 …

AI+教育|拥抱AI智能科技,让课堂更生动高效

AI在教育领域的应用正逐渐成为现实&#xff0c;提供互动性强的学习体验&#xff0c;正在改变传统教育模式。AI不仅改变了传统的教学模式&#xff0c;还为教育提供了更多的可能性和解决方案。从个性化学习体验到自动化管理任务&#xff0c;AI正在全方位提升教育质量和效率。随着…

观察者模式全攻略:从设计原理到 SpringBoot 实践案例

&#x1f3af; 设计模式专栏&#xff0c;持续更新中~~ 欢迎订阅&#xff1a;JAVA实现设计模式 &#x1f6e0;️ 希望小伙伴们一键三连&#xff0c;有问题私信都会回复&#xff0c;或者在评论区直接发言 观察者模式 观察者模式&#xff08;Observer Pattern&#xff09;是一种行…

web学习——VUE

VUE&Element 今日目标&#xff1a; 能够使用VUE中常用指令和插值表达式能够使用VUE生命周期函数 mounted能够进行简单的 Element 页面修改能够完成查询所有功能能够完成添加功能 1&#xff0c;VUE 1.1 概述 接下来我们学习一款前端的框架&#xff0c;就是 VUE。 Vue 是…

JAVA并发编程系列(8)CountDownLatch核心原理

拼多多 D2面试&#xff0c;现场编程模拟拼团&#xff0c;10人拼团成功。限时2分钟&#xff01;开始吧.....&#xff01;在面试过程经常有算法题、模拟现实案例、经典功能设计、核心原理分析这种。这些看似简单&#xff0c;实际需要候选人有非常扎实的基础&#xff0c;才能应付这…

maxwell 输出消息到 kafka

文章目录 1、kafka-producer2、运行一个Docker容器&#xff0c;该容器内运行的是Zendesk的Maxwell工具&#xff0c;一个用于实时捕获MySQL数据库变更并将其发布到Kafka或其他消息系统的应用3、进入kafka容器内部4、tingshu_album 数据库中 新增数据5、tingshu_album 数据库中 更…

【Django5】django的helloworld

安装django pip install djangoDjango官方中文文档 https://docs.djangoproject.com/zh-hans/5.1/Github链接 https://github.com/django/django创建Django项目 cd到想要创建项目的文件夹下&#xff0c;输入以下命令创建项目 这行代码将会在当前目录下创建一个 mysite 目录 …

Seeing What You Said Talking Face Generation Guided论文随记

Seeing What You Said Talking Face Generation Guided by a Lip Reading Expert 文章认为以往工作很少关注唇语清晰度&#xff0c;希望通过惩罚不准确结果来提升唇部区域动作的可理解性。 原文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Wang_…

【吊打面试官系列-MySQL面试题】LIKE 声明中的%和_是什么意思?

大家好&#xff0c;我是锋哥。今天分享关于【LIKE 声明中的&#xff05;和_是什么意思&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; LIKE 声明中的&#xff05;和_是什么意思&#xff1f; &#xff05;对应于 0 个或更多字符&#xff0c;_只是 LIKE 语句中的…

PSINS工具箱函数介绍——myfig

文章目录 关于工具箱使用方法与主要作用例程实践运行代码函数解析关于工具箱 myfig是关于绘图的函数,位置在: p s i n s / b a s e / p l o t psins/\ base/\ plot

深入理解 Linux 内核网络协议栈

Linux 作为全球广泛应用的操作系统&#xff0c;凭借其稳定、高效和开源的特点&#xff0c;已成为服务器、嵌入式系统和个人电脑等领域的首选系统。而在 Linux 系统的核心中&#xff0c;网络协议栈承担了网络数据通信的关键任务。理解 Linux 内核网络协议栈的工作原理&#xff0…

加密与安全_三种常见的注入攻击

文章目录 概述注入攻击类型及危害注入攻击的工作原理SQL注入代码注入XSS&#xff08;跨站脚本&#xff09; SQL注入SQ L注入攻击的本质常见误区及注入点误区1&#xff1a;SQL注入仅发生在GET请求中误区2&#xff1a;没有返回数据的接口不易受注入影响误区3&#xff1a;SQL注入的…

SpringSecurity原理解析(八):CSRF防御解析

一、CsrfFilter CsrfFilter 主要功能是用来防止csrf攻击 一、什么是CSRF攻击 跨站请求伪造&#xff08;英语&#xff1a;Cross-site request forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;通常缩写为 CSRF 或者 XSRF&#xff0c…

关于广告投放平台的设计

文章目录 广告投放平台的作用广告平台的核心功能 最近在看关于广告投放平台相关的设计&#xff0c;倒是没看到完整的案例介绍。整理一下收集的各种信息&#xff0c;假如需要设计一个广告投放系统&#xff0c;该怎么做&#xff1f; 广告投放平台的作用 要体现广告投放平台的作用…

如何实现LLM的通用function-calling能力?

众所周知&#xff0c;LLM的函数function-calling能力很强悍&#xff0c;解决了大模型与实际业务系统的交互问题。其本质就是函数调用。 从openai官网摘图&#xff1a; 简而言之&#xff1a; LLM起到决策的作用&#xff0c;告知业务系统应该调用什么函数&#xff0c;以及入参是…

动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目

一、介绍 动物识别系统。本项目以Python作为主要编程语言&#xff0c;并基于TensorFlow搭建ResNet50卷积神经网络算法模型&#xff0c;通过收集4种常见的动物图像数据集&#xff08;猫、狗、鸡、马&#xff09;然后进行模型训练&#xff0c;得到一个识别精度较高的模型文件&am…