Spring源码学习-核心注解,架构以及整体流程

目录

    • 核心注解
    • 核心组件接口分析
      • 基础接口
        • Resource+ResourceLoader
          • Resource
          • ResourceLoader
        • BeanFactory
          • 结构解析图示
          • 核心的子接口
        • BeanDefinition
          • 加载注册流程(xml形式的)
        • BeanDefinitionReader
        • BeanDefinitionRegistry
        • ApplicationContext
          • 类结构图示
          • 结构解析
        • Aware
          • 接口类图
          • xxAware是什么时候赋值进来
          • 判断后置处理器
      • 基础类
        • DefaultListableBeanFactory
        • DefaultSingletonBeanRegistry
        • GenericApplicationContext

核心注解

注解功能
@Bean容器中注册组件
@Primary同类组件如果有多个,标注主组件
@DependsOn组件之间声明依赖关系
@Lazy组件懒加载(最后使用的时候才创建)
@Scope声明组件的作用范围(SCOPE_PROTOTYPE,SCOPE_SINGLETON)
@Configuration声明这是一个配置类,替换以前配置文件
@Component@Controller、@Service、@Repository
@Indexed加速注解,所有标注了 @Indexed 的组件,直接会启动快速加载
@Order数字越小优先级越高,越先工作
@ComponentScan包扫描
@Conditional条件注入
@Import导入第三方jar包中的组件,或定制批量导入组件逻辑
@ImportResource导入以前的xml配置文件,让其生效
@Profile基于多环境激活
@PropertySource外部properties配置文件和JavaBean进行绑定.结合ConfigurationProperties
@PropertySources@PropertySource组合注解
@Autowired自动装配
@Qualifier精确指定
@Value取值、计算机环境变量、JVM系统。xxxx。@Value(“${xx}”)
@Lookup单例组件依赖非单例组件,非单例组件获取需要使用方法

注:@Indexed 需要引入依赖

	<groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><optional>true</optional>
</dependency>```

核心组件接口分析

基础接口

Resource+ResourceLoader

Resource

它是spring自己定义的一个资源抽象接口,表示所有需要加载到spring的bean容器中的资源,来自于xml以及注解的bean,甚至是网络和本地磁盘当中,都可以用它表示

ResourceLoader

spring定义的资源加载器(策略模式接口),通过不同的策略实现,加载不同情况的bean封装为resource资源
AbstractApplicationContext作为环境类持有ResourcePatternResolver接口(通过这个策略模式去调用真正的资源加载实现类)

BeanFactory

作为spring的一个基础的抽象工厂接口

结构解析图示

BeanFactory

核心的子接口
  • HierarchicalBeanFactory:定义父子工厂(父子容器)
  • ListableBeanFacotory:的实现是DefaultListableBeanFactory,保存了ioc容器中的核心信息
  • AutowireCapableBeanFactory:提供自动装配能力
  • AnnotationApplicationContext组合了档案馆,他有自动装配能力

BeanDefinition

Bean的定义信息接口,封装bean需要的信息属性

加载注册流程(xml形式的)

加载注册流程

他会被BeanDefinitionHolder类进行一层封装,它封装了bean的名称和别名数组,以及BeanDefinition自身,方便后续对他的处理操作

BeanDefinitionReader

读取Bean信息的策略接口,他是Bean信息的一个读取器,他有XmlBeanDefinitionReader具体的实现类用来读取xml中的bean配置信息.它本身也持有IOC容器类的环境,组合传进去的

BeanDefinitionParserDelegate用来解析从xml配置文件读取到的Dom文档(解释器模式)
读取器具体的实现又去组合资源加载策略接口ResourceLoader(Spring中运用了相当之多的组合,他在组合与继承以及接口之间做了相当美妙的平衡,我觉得这里面才是值得仔细去思考和学习的)

BeanDefinitionRegistry

bean定义信息注册中心,提供一个必须要实现的registerBeanDefinition方法,由具体的类去实现

ApplicationContext

类结构图示

ApplicationContext

结构解析
  • IOC事件派发器
  • 国际化解析
  • bean工厂功能–自动装配是被组合进来的
  • 资源解析功能

Aware

接口类图

Aware

xxAware是什么时候赋值进来

xxAware

判断后置处理器
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||bean instanceof ApplicationStartupAware)) {return bean;}

先去缓存的单实例池拿到bean,拿不到的话再去创建

基础类

DefaultListableBeanFactory

这是spring的关键类,属于是spring的’档案馆’,他继承和实现一系列的接口并且通过组合的方式,保存了spring的bean实例信息(通过多个ConcurrentHashMap),后续spring拿到这些读取到的bean图纸信息,再根据信息去创建相应的Bean

//组合模式,Spring里面允许有很多工厂(工厂之间的bean可以隔离开 不过实际上目前没有这么使用过的)private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =new ConcurrentHashMap<>(8);
/** Map of bean definition objects, keyed by bean name. *///所有BeanDefinition信息按照名字对应BeanDefinition关系都保存好了private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map of singleton-only bean names, keyed by dependency type. *///Spring中按照类型得到组件的一个底层池//按照类型保存单实例bean的名称private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** List of bean definition names, in registration order. *///保存所有bean定义的名称private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

结构图示

DefaultSingletonBeanRegistry

这是spring的单例对象缓存池,包括三级缓存也是在这个类中。

/** spring是使用享元完成单例模式,使用单例对象池(单例享元池返回组件) */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

GenericApplicationContext

将上面的DefaultListableBeanFactory组合进来用来存储bean的定义和信息,通过继承资源类和实现ApplicationContext接口获得ioc容器

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

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

相关文章

什么是计算机蠕虫?

计算机蠕虫诞生的背景 计算机蠕虫的诞生与计算机网络的发展密切相关。20世纪60年代末和70年代初&#xff0c;互联网还处于早期阶段&#xff0c;存在着相对较少的计算机和网络连接。然而&#xff0c;随着计算机技术的进步和互联网的普及&#xff0c;计算机网络得以迅速扩张&…

Windows系统如何查看物理cpu核数?

Step1&#xff1a;WinR 打开cmd; Step2&#xff1a;输入dxdiag后&#xff0c;回车&#xff1b; Step3&#xff1a;即可查看&#xff1a;

M1 Mac如何安装CentOS7虚拟机(图文详细解说)

1、下载相应的文件 2、打开VMware Fusion pro进行安装 3、 输入许可证密钥 4、 将CentOS-7拖入“从光盘或映像中安装”中 5、点击继续 6、选择其他-->其他64位ARM-->继续 7、进行自定设置 8、这里更改名为“Centos7”&#xff08;不要加空格&#xff09;&#xff0c;存…

【力扣算法14】之 15. 三数之和 python

问题描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意&#xff1a;**答案中不可以包含重复的三元…

程序环境和预处理

程序环境 分为翻译环境和执行环境 在 ANSI C 的任何一种实现中&#xff0c;存在两个不同的环境。 第 1 种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境&#xff0c;它用于实际执行代码。 翻译环境&#xff1a;C语言代码-->二进…

数据库系统 - 家庭教育平台设计开发

目录 1.绪论 1.1项目背景 1.2家庭教育平台的发展现状与优势 1.2.1国内外发展现状 1.2.2家庭教育平台的优势 2.需求分析 2.1可行性分析 2.1.1经济可行性 2.1.2 技术可行性 2.1.3操作可行性 2.2系统功能 2.2.1 家庭教育资源 2.2.2 家庭教育指导师 2.2.3家庭教育咨询…

Jupyter入门使用教程

1 Jupyter Notebook与Jupyter Lab简介 Jupyter Notebook是一个开源的Web应用&#xff0c;在深度学习领域非常活跃。用户可以在这里创建和分享可执行代码、可视化结构和注释说明的文档。 Jupyter Notebook以网页的形式展现&#xff0c;用户可以在此网页中直接编辑代码、运行程…

提升互联网创业项目在搜索结果中的排名的SEO技巧

搜索引擎优化(SEO)技巧&#xff1a;提升互联网创业项目在搜索结果中的排 在当今竞争激烈的互联网创业领域&#xff0c;拥有一个高排名的搜索结果对于项目的成功至关重要。搜索引擎优化&#xff08;SEO&#xff09;是一种有效的策略&#xff0c;可以提高您的互联网创业项目在搜索…

MySQL数据表高级操作

一、克隆/复制数据表二、清空表&#xff0c;删除表内的所有数据删除小结 三、创建临时表四、MySQL中6种常见的约束1、外键的定义2、创建外键约束作用3、创建主表test44、创建从表test55、为主表test4添加一个主键约束。主键名建议以"PK_”开头。6、为从表test5表添加外键&…

基于simulink的DPLL仿真笔记

该笔记主要用于本人思路整理与记录 本设计运用的是电荷泵一阶环路滤波器&#xff0c;二阶三阶则在此基础上举一反三&#xff0c;以后如有机会会慢慢补全 文章目录 一.仿真模型PS&#xff08;题外话&#xff09; 二.仿真结果三.环路滤波器分析1. 环路滤波器对比LPF2. 环路滤波器…

Linux嵌入式项目-智能家居

一、资料下载 二、框架知识 三、MQTT通信协议 1、上位机APP主要工作 1.wait for msg / while(1)订阅等待消息 2.处理消息 客户端创建了两个线程&#xff0c;一个线程用于发布消息&#xff0c;一个线程用于监听订阅消息 &#xff08;那我的仿真系统也可以啊&#xff0c;一个…

Braindecode系列 (4):使用自定义数据集

Braindecode系列&#xff1a;使用自定义数据集 0. 引言1. 数据转换步骤说明1.1 加载库包1.2 加载数据1.3 提取信息1.4 数据转换1.5 数据操作 2. 示例3. 总结 0. 引言 在Braindecode系列中&#xff0c;我会介绍跟BCI IV 2a有关的所有相关示例。 在前面的章节中&#xff0c;我们…