十二、Spring源码学习之finishBeanFactoryInitialization方法

finishBeanFactoryInitialization()方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.//初始化上下文类型转换服务if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.//是用于检查 Bean 工厂是否具有嵌入式值解析器的方法。// 在 Spring 中,嵌入式值解析器用于解析 Bean 定义中的占位符,例如 ${...} 或者 #{...},// 并将其替换为相应的值。通过调用 hasEmbeddedValueResolver() 方法,// 可以判断 Bean 工厂是否已配置嵌入式值解析器,以便在需要时进行值的解析和替换操作。//解析bean中的占位符if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.//初始化实现了LoadTimeWeaverAware接口的类 这个用于类加载时织入//类加载时的织入是 AspectJ 的一个特性,允许在类被加载到 JVM 之前应用切面(Aspect)逻辑String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.//停止使用临时类加载器beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.//是用于锁定 Spring 应用程序上下文或 Bean 工厂的配置的方法。在调用 freezeConfiguration() 方法后,// 将无法更改应用程序上下文或 Bean 工厂的配置,这意味着不能再向上下文或 Bean 工厂中添加或更改 Bean 定义、修改属性、或在上下文中加载新的配置文件等。//一旦调用了 freezeConfiguration() 方法,应用程序上下文或 Bean 工厂就被认为是只读的,并且可以在多线程环境中安全地使用。// 这个方法在应用程序上下文或 Bean 工厂初始化完成后调用,以确保配置的完整性和不可更改性。beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.//是用于预初始化单例 Bean 的方法。在 Spring 容器启动时,如果某些 Bean 的作用域为 Singleton,// 且其 lazy-init 属性为 false,那么 Spring 会在容器初始化的过程中自动对这些 Bean 进行实例化。// 但是,如果你想在容器初始化的早期手动触发所有单例 Bean 的实例化过程,// 你可以调用 preInstantiateSingletons() 方法。//调用 preInstantiateSingletons() 方法将导致容器立即实例化所有标记为 Singleton 且非懒加载的 Bean,// 以确保这些 Bean 在容器生命周期的早期阶段就已经被创建。这个方法通常在 Spring 容器启动后的某个时刻被调用,// 它可以保证当你需要使用某些 Singleton Bean 时,它们已经被完全创建和初始化。// 这样可以避免在运行时因为延迟实例化而产生的潜在性能问题或并发问题。beanFactory.preInstantiateSingletons();}

DefaultListableBeanFactory#freezeConfiguration()方法

public void freezeConfiguration() {this.configurationFrozen = true;//配置锁定,不允许更改//锁定bean 不允许更改this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);}

DefaultListableBeanFactory#preInstantiateSingletons()方法

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.//拿到所有的beanNameList<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...//初始化非懒加载的beanfor (String beanName : beanNames) {//将bean进行合并处理之后返回 RootBeanDefinition 作为最终初始化的bean使用RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//bd 不是抽象类 && 是单例的 && 不是懒加载的if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {//判断当前bean是一个FactoryBean//回去FactoryBean对象本身Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {//判断当前bean的类型是FactoryBeanFactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {//判断bean 是否需要更早期的初始化isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}//为true 则在容器启动时立即初始化if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {//再次遍历所有的已创建和的单例beanObject singletonInstance = getSingleton(beanName);//获取单例bean 并且判断该bean的类型是SmartInitializingSingletonif (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {//则调用afterSingletonsInstantiated方法smartSingleton.afterSingletonsInstantiated();}}}}

AbstractBeanFactory#getMergedLocalBeanDefinition()方法

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;// Check with full lock now in order to enforce the same merged instance.if (containingBd == null) {//从合并bean缓存中获取mbd = this.mergedBeanDefinitions.get(beanName);}if (mbd == null) {//如果不存在if (bd.getParentName() == null) {//判断当前bean的是否父bean不存在// Use copy of given root bean definition.if (bd instanceof RootBeanDefinition) {//并且当前的类型是RootBeanDefinition 则克隆一个mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {//否则创建一个新的RootBeanDefinitionmbd = new RootBeanDefinition(bd);}}else {// Child bean definition: needs to be merged with parent.BeanDefinition pbd;try {//如果存在父beanString parentBeanName = transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {//递归调用父bean的beanpbd = getMergedBeanDefinition(parentBeanName);}else {//从工厂中获取父beanBeanFactory parent = getParentBeanFactory();if (parent instanceof ConfigurableBeanFactory) {pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.//创建一个新的RootBeanDefinitionmbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);}// Set default singleton scope, if not configured before.if (!StringUtils.hasLength(mbd.getScope())) {//设置bean的作用域mbd.setScope(SCOPE_SINGLETON);}// A bean contained in a non-singleton bean cannot be a singleton itself.// Let's correct this on the fly here, since this might be the result of// parent-child merging for the outer bean, in which case the original inner bean// definition will not have inherited the merged outer bean's singleton status.if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {//使用之前的scopembd.setScope(containingBd.getScope());}// Cache the merged bean definition for the time being// (it might still get re-merged later on in order to pick up metadata changes)if (containingBd == null && isCacheBeanMetadata()) {//将新的合并好的bean放入缓存中this.mergedBeanDefinitions.put(beanName, mbd);}}//如果存在 则直接返回return mbd;}}

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

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

相关文章

搭建机器人产业发展重要展示平台“2024南京国际机器人展览会”

2024南京国际智能机器人展览会 2024 Nanjing Intelligent Robot Expo 时间:2024年11月22-24日 地点:南京国际博览中心 南京&#xff0c;这座历史悠久的文化名城&#xff0c;如今正站在机器人产业发展的前沿。随着全球科技的飞速进步&#xff0c;机器人产业已经成为推动经济社…

C 语言贪吃蛇源码解析

贪吃蛇是一款经典的电子游戏&#xff0c;玩家控制一条不断成长的蛇&#xff0c;需要避免撞到自己的身体或者游戏边界&#xff0c;同时吃掉出现在屏幕上的食物以增长身体长度。 下面是一个简单的贪吃蛇游戏的C语言实现&#xff0c;使用了标准输入输出库conio.h和时间库windows.h…

数电票怎么查询真伪|发票识别接口|发票查验接口|PHP接口文档

对于财务工作者而言&#xff0c;发票管理是一项即繁琐又十分重要的工作&#xff0c;尤其是在数字化电子发票快速普及的当下&#xff0c;发票识别、核验、查重等工作无疑增加了财务人员的工作难度。财务人员每天都要与大量的发票打交道&#xff0c;人工管理模式难免会出现手动录…

C语言二叉树和堆(个人笔记)

二叉树和堆 二叉树1二叉树的概念和结构1.1特殊的二叉树1.2二叉树的性质&#xff08;规定根节点的层数为1&#xff09;1.3二叉树的存储结构 2.二叉树的顺序结构和实现2.1二叉树的顺序结构2.2堆的概念和结构2.3堆的实现2.4堆的应用2.4.1堆排序 2.5TOP-K问题 3.二叉树的遍历4.二叉…

追光而遇 沐光同行——锐捷网络召开2024教育行业核心合作伙伴论坛

3月21日,主题为“追光而遇 沐光同行”的2024锐捷网络教育行业核心伙伴论坛在福州启幕。论坛汇聚了教育行业的精英与合作伙伴,议题主要聚焦于教育行业的数字化转型与创新发展,以及如何通过技术驱动,构建智慧教育生态,推动教育事业的高质量发展。作为行业领先的ICT基础设施及解决…

Spring实战:采用Spring配置文件管理Bean

文章目录 一、Spring框架概述二、实战&#xff1a;采用Spring配置文件管理Bean&#xff08;一&#xff09;创建Jakarta EE项目&#xff08;二&#xff09;添加Spring依赖&#xff08;三&#xff09;创建杀龙任务类&#xff08;四&#xff09;创建勇敢骑士类&#xff08;五&…

【No.19】蓝桥杯简单数论上|模运算|快速幂|GCD|LCM|刷题统计|RSA解密|核桃的数量(C++)

简单数论 模运算 定义&#xff1a;模运算为 a 除以 m 的余数&#xff0c;记为 a mod m&#xff0c;有 a mod m a % m模运算是大数运算中的常用操作。如果一个数太大&#xff0c;无法直接输出&#xff0c;或者不需要直接输出&#xff0c;可以把它取模后&#xff0c;缩小数值再…

聚观早报 | 比亚迪2023年营收;vivo X Fold3系列发布

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 3月28日消息 比亚迪2023年营收 vivo X Fold3系列发布 现代汽车拟投入68万亿韩元 华为P70系列最新渲染图 苹果A1…

C语言牛客网BC-37 牛牛的圆(求面积)

题目如下 代码实现 #include<stdio.h> int main() { float r 0;float s 0;scanf("%f",&r);s 3.14*r*r;printf("%.2f",s);return 0; } 创作不易&#xff0c;点点关注&#xff0c;感谢支持&#xff01;&#xff01;&#xff01;

[BT]BUUCTF刷题第9天(3.27)

第9天&#xff08;共2题&#xff09; [护网杯 2018]easy_tornado 打开网站就是三个txt文件 /flag.txt flag in /fllllllllllllag/welcome.txt render/hints.txt md5(cookie_secretmd5(filename))当点进flag.txt时&#xff0c;url变为 http://b9e52e06-e591-46ad-953e-7e8c5f…

SAP Fiori开发中的JavaScript基础知识5 - 对象(Object)

1 背景 在本篇博客中&#xff0c;我将介绍JavaScript中对象&#xff08;Object&#xff09;的概念和用法。 2 对象 首先我们要明明确一点&#xff0c;在JavaScript中对象&#xff08;Object&#xff09;和类&#xff08;Class&#xff09;是不同的&#xff0c;它们是两个不同…

《论文阅读》PAGE:一个用于会话情绪原因蕴含基于位置感知的图模型 ICASSP 2023

《论文阅读》PAGE&#xff1a;一个用于会话情绪原因蕴含基于位置感知的图模型 ICASSP 2023 前言 简介任务定义模型构架Utterances Encoding with EmotionPosition-aware GraphCausal Classifier实验结果 前言 亲身阅读感受分享&#xff0c;细节画图解释&#xff0c;再也不用担…

极简wordpress网站模板

Pithy设计师wordpress网站模板 精练简洁的wordpress模板&#xff0c;设计师或设计工作室展示型网站模板。 https://www.jianzhanpress.com/?p6329

Clickhouse中的基本数据类型操作和引擎

一、表操作 数据类型: 注意事项&#xff1a; 1、建表写数据类型的时候&#xff0c;严格区分大小写Int32,不能写成int32 2、建表的时候&#xff0c;必须要指定表引擎 1.整数类型 2. 字符串类型 String&#xff1a;可以任意长度的。它可以包含任意的字节集&#xff0c;包含空字…

Avalonia笔记4-Rider如何添加xaml支持

在Linux Rider中&#xff0c;File Type中是有XAML文件的&#xff0c;但是新增xaml文件并不能正确的添加到项目中&#xff0c;而且就算是新增文件&#xff0c;直接命名为“XXX.xaml”&#xff0c;也是没有智能提示的。 在引用Style文件的时候&#xff0c;需要新建一个axaml的文…

【uniapp】Vue3移动端滚动加载 分页组件的封装

今天用uniapp开发时想用vue3的组合式函数封装一个分页组件&#xff0c;如果是vue2自然就是用mixin了&#xff0c;因为组合式函数更灵活简洁&#xff0c;而且现在也写习惯了&#xff0c;还是决定封装一个vue3版的。 思路&#xff1a; 因为uniapp特有的对一些小程序生命周期的支…

2024,听世界用中文讲故事

汉语为桥&#xff0c;联结一段中国缘分&#xff1b;故事为骨&#xff0c;分享一段精彩人生&#xff1b;文化为翼&#xff0c;共筑一个和美地球村。近日&#xff0c;由教育部中外语言交流合作中心主办、中文联盟承办的第二届“汉语桥”全球外国人汉语大会故事会启动。与世界深情…

k8s调优--来自gpt

Kubernetes&#xff08;K8s&#xff09;性能调优是一个涉及多个方面的过程&#xff0c;旨在提高集群的效率和响应速度。这包括对节点、Pod、服务、网络和存储等多个层面进行调优。下面我将概述一些常见的Kubernetes性能调优方法&#xff1a; 节点级别的调优: 1.资源分配&…

网站可扩展架构设计

从公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- 一、可扩展性架构简介 1.可扩展性是什么 可扩展性指系统为了应对将来需求变化而提供的一种扩展能力&#xff0c;当有新的需求出现时&#xff0c;系…

【数据结构】链表习题之反转链表和删除链表中等于给定值 val 的所有节点

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 今天的博客是关于链表的题目&#xff0c;力扣上的题目之反转链表和删除链表中等于给定值 val 的所有节点 一.反转…