如何学习 Spring ?学习 Spring 前要学习什么?

整理了一下Spring的核心概念BeanDefinitionBeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点。比如:class,表示Bean类型scope,表示Bean作用域,单例或原型等lazyInit:表示Bean是否是懒加载initMethodName:表示Bean初始化时要执行的方法destroyMethodName:表示Bean销毁时要执行的方法还有很多…在Spring中,我们经常会通过以下几种方式来定义Bean:@Bean@Component(@Service,@Controller)这些,我们可以称之申明式定义Bean。我们还可以编程式定义Bean,那就是直接通过BeanDefinition,比如:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
context.registerBeanDefinition("user", beanDefinition);System.out.println(context.getBean("user"));

我们还可以通过BeanDefinition设置一个Bean的其他属性

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

和申明式事务、编程式事务类似,通过,@Bean,@Component等申明式方式所定义的Bean,最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。

BeanDefinitionReader

接下来,我们来介绍几种在Spring源码中所提供的BeanDefinition读取器(BeanDefinitionReader),这些BeanDefinitionReader在我们使用Spring时用得少,但在Spring源码中用得多,相当于Spring源码的基础设施。AnnotatedBeanDefinitionReader可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,比如

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

注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description

XmlBeanDefinitionReader

可以解析标签

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

ClassPathBeanDefinitionScannerClassPathBeanDefinitionScanner是扫描器,但是它的作用和BeanDefinitionReader类似,它可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition,比如:

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

BeanFactory
BeanFactory表示Bean工厂,所以很明显,BeanFactory会负责创建Bean,并且提供获取Bean的API。

而ApplicationContext是BeanFactory的一种,在Spring源码中,是这么定义的:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {...
}

作者:约一夏萌宠屋
链接:https://www.zhihu.com/question/438612354/answer/2663530822
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先,在Java中,接口是可以多继承的,我们发现ApplicationContext继承了ListableBeanFactory和HierarchicalBeanFactory,而ListableBeanFactory和HierarchicalBeanFactory都继承至BeanFactory,所以我们可以认为ApplicationContext继承了BeanFactory,相当于苹果继承水果,宝马继承汽车一样,ApplicationContext也是BeanFactory的一种,拥有BeanFactory支持的所有功能,不过ApplicationContext比BeanFactory更加强大,ApplicationContext还基础了其他接口,也就表示ApplicationContext还拥有其他功能,比如MessageSource表示国际化,ApplicationEventPublisher表示事件发布,EnvironmentCapable表示获取环境变量,等等,关于ApplicationContext后面再详细讨论。在Spring的源码实现中,当我们new一个ApplicationContext时,其底层会new一个BeanFactory出来,当使用ApplicationContext的某些方法时,比如getBean(),底层调用的是BeanFactory的getBean()方法。在Spring源码中,BeanFactory接口存在一个非常重要的实现类是:**DefaultListableBeanFactory,也是非常核心的。**具体重要性,随着后续课程会感受更深。所以,我们可以直接来使用DefaultListableBeanFactory,而不用使用ApplicationContext的某个实现类,比如:

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);beanFactory.registerBeanDefinition("user", beanDefinition);System.out.println(beanFactory.getBean("user"));

DefaultListableBeanFactory是非常强大的,支持很多功能,可以通过查看DefaultListableBeanFactory的类继承实现结构来看
在这里插入图片描述
作者:约一夏萌宠屋
链接:https://www.zhihu.com/question/438612354/answer/2663530822
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这部分现在看不懂没关系,源码熟悉一点后回来再来看都可以。它实现了很多接口,表示,它拥有很多功能:AliasRegistry:支持别名功能,一个名字可以对应多个别名Bean
DefinitionRegistry:可以注册、保存、移除、获取某个Bean
DefinitionBeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象
SingletonBeanRegistry:可以直接注册、获取某个单例Bean
SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能
ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有Bean
Definition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系
HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能
ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能FactoryBeanRegistrySupport:支持了FactoryBean的功能AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNamesConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactoryAbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

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

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

相关文章

Matlab 在一个文件中调用另一个文件中的函数

文章目录 Part.I IntroductionPart.II 方法Chap.I A 文件中只有一个函数Chap.II A 文件中有多个函数 Part.I Introduction 本文介绍一下在脚本文件 B 中调用文件 A 中的函数的方法。 Part.II 方法 目的:在文件B.m调用A.m中的函数 默认两个文件在一个文件夹下&…

Python中查看对象的所有属性和方法以及查看属性是否存在

Python中查看对象的所有属性和方法以及查看属性是否存在 作者:爱编程的小金毛球球 日期:2023年12月3日 Python提供许多的内置函数和模块来帮助开发人员查看对象的所有属性,例如:dir(),vars(),__dict__等。 …

深度学习好文记录,反复学习

recent update time:2023.12.2 深度学习入门 - 知乎、这本书也很好,作者写的专栏不错。 机器学习,深度学习一些好文_一只菜得不行的鸟的博客-CSDN博客 卷积神经网络学习路线(五)| 卷积神经网络参数设置,提…

Python 错误 TypeError: __str__ Returned Non-String but Printing Output

本文旨在解决当我们尝试打印字符串而不是在函数中使用 return 语句时出现的问题。 Python 返回非字符串错误但打印输出 以下代码显示了 TypeError: str returned non-string,但它仍然打印输出。 示例代码: class xy:def __init__(self, x, y):self.x …

华为OD机试真题-靠谱的车-2023年OD统一考试(C卷)

题目描述: 程序员小明打了一辆出租车去上班。出于职业敏感,他注意到这辆出租车的计费表有点问题,总是偏大。 出租车司机解释说他不喜欢数字4,所以改装了计费表,任何数字位置遇到数字4就直接跳过,其余功能都正常。 比如: 1. 23再多一块钱就变为25; 2. 39再多一块…

力扣611题 有效三角形的个数 双指针算法

611. 有效三角形的个数 给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。 示例 1: 输⼊: nums [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使⽤第⼀个 2) 2,3,4 (使⽤第⼆个 2) 2,2,3 ⽰例 2: 输⼊: nums [4,2,3,4] 输出: 4 解…

Topic和Partition

作用 主题作为消息的一级分类, 分区是对二级分类。分区是Kafka可伸缩性和水平扩展的关键, 也是多副本机制保证可用性的基础。分区可以有一到多个副本, 每个副本对应1个日志文件, 每个日志文件对应1到多个日志分段。每个日志分段又可以细分为日志文件, 索引文件和快照文件。 创…

CAP概念和三种情况、Redis和分布式事务的权衡

借鉴:https://cloud.tencent.com/developer/article/1840206 https://www.cnblogs.com/huanghuanghui/p/9592016.html 一:CAP概念和三种情况 1.概念: C全称Consistency(一致性):这个表示所有节点返回的数…

轻易云AI:引领企业数智化转型提升企业AI效率

近期,轻易云AI与汤臣倍健的合作引起了业界的广泛关注。通过这一合作,轻易云AI不仅成功打造了集团小汤AI助手这一标志性的企业智能助手,更重要的是,这一合作凸显了轻易云AI作为专业AI应用集成专家的核心能力。轻易云AI已成功集成了…

Spring之RestTemplate详解

Spring之RestTemplate详解 1 RestTemplate1.1 引言1.2 环境配置1.2.1 非Spring环境下使用RestTemplate1.2.2 Spring环境下使用 RestTemplate1.2.3 Spring环境下增加线程号 1.3 API 实践1.3.1 GET请求1.3.1.1 不带参请求1.3.1.2 带参的get请求(使用占位符号传参)1.3.1.3 带参的g…

创建内存泄漏(js的问题)

如果没有有意识地编写代码来避免内存泄漏,那么内存泄漏几乎是不可避免的JavaScript问题。它们的发生方式有很多种,所以我们只重点介绍几种比较常见的情况。 内存泄漏实例1:对不存在的对象的悬空引用 考虑以下代码: var theThing null; var replaceTh…

Redis7--基础篇4(Redis事务)

Redis事务是什么 可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序串行,而不会被其他命令插入。 其作用就是在一个队列中,一次性、顺序、排他的执行一系列命令。 Redis事务 VS 数据…

【每日一题】拼车+【差分数组】

文章目录 Tag题目来源解题思路方法一:差分 写在最后 Tag 【差分数组】【数组】【2023-12-02】 题目来源 1094. 拼车 解题思路 本题朴素的解题思路是统计题目中提到的每一个站点的车上人数,如果某个站点的车上人数大于车上的座位数直接返回 false&…

SSE4.2 指令集内置函数来加速32位循环冗余校验(CRC-32)计算

1、_mm_crc32_u8 为什么比查表快? _mm_crc32_u8 指令使用了 SIMD 技术(即单指令多数据流技术),可以同时处理多个字节的数据。这些字节被打包成 64 位整数,然后使用单条 _mm_crc32_u64 指令计算它们的 CRC-32 校验和。…

基于 Vue、Datav、Echart 框架的 “ 数据大屏项目 “,通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换

最近在研究大数据分析,基于 Vue、Datav、Echart 框架的 " 数据大屏项目 ",通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换。部分图表使用 DataV 自带组件,可进行更改,详情请点击下方 DataV 文档…

flask中遇到ImportError: cannot import name ‘url_encode‘ from ‘werkzeug‘

报错信息 Traceback (most recent call last): File “book_management_sys.py”, line 5, in from forms import Login, SearchBookForm, ChangePasswordForm, EditInfoForm, SearchStudentForm, NewStoreForm, StoreForm, BorrowForm File “C:\pythonProject\pythonProject…

abapgit 安装及使用

abapgit 需求 SA[ BASIS 版本 702 及以上 版本查看路径如下: 安装步骤如下: 1. 下载abapgit 独立版本 程序 链接如下:raw.githubusercontent.com/abapGit/build/main/zabapgit_standalone.prog.abap 2.安装开发版本 2.1 在线安装 前置条…

【C++】类和对象——初始化列表和static修饰成员

首先我们来谈一下初始化列表,它其实是对于我们前边构造函数体内初始化的一种补充,换一种说法,它以后才是我们构造函数的主体部分。 我们先考虑一个问题,就是一个类里面有用引用或const初始化的成员变量,比如说&#xf…

HTML_web扩展标签

1.表格标签 2.增强表头表现 4.表格属性(实际不常用) 结构标签: 合并单元格: 更多请查看主页