Spring源码(八)--Spring实例化的策略
Spring实例化的策略有几种 ,可以看一下 InstantiationStrategy 相关的类。
UML 结构图
InstantiationStrategy的实现类有 SimpleInstantiationStrategy。 CglibSubclassingInstantiationStrategy 又继承了SimpleInstantiationStrategy。

InstantiationStrategy
InstantiationStrategy . 实例化的策略, 可以根据 给定名称及默认的构造函数、 或者是指定的构造函数、 工厂方法 实例化。
InstantiationStrategy 源码如下:
/*** 负责创建与基础bean定义相对应的实例。*/
public interface InstantiationStrategy {/*** 根据给定名称,返回该工厂中的bean实例。使用默认的构造函数。*/Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)throws BeansException;/*** 返回该工厂中具有给定名称的bean实例,并通过给定构造函数创建它。*/Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,Constructor<?> ctor, @Nullable Object... args) throws BeansException;/*** 返回该工厂中具有给定名称的bean实例,并通过给定的工厂方法创建它。*/Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, Method factoryMethod, @Nullable Object... args)throws BeansException;}
SimpleInstantiationStrategy
InstantiationStrategy 实现了 SimpleInstantiationStrategy.
SimpleInstantiationStrategy 调用的方法栈如下:
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:155)at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$195.404947798.getObject(Unknown Source:-1)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:171)at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
- ConstructorResolver.instantiate 实例化:
ConstructorResolver.instantiate 会先获取对应的策略,然后再实例化。
方法具体路径:
org.springframework.beans.factory.support.ConstructorResolver#instantiate(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
代码如下:
private Object instantiate(String beanName, RootBeanDefinition mbd,@Nullable Object factoryBean, Method factoryMethod, Object[] args) {try {if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedAction<Object>) () ->this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),this.beanFactory.getAccessControlContext());}else {// 关键看这一句, 先获取对应的策略,然后再实例化。return this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);}}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean instantiation via factory method failed", ex);}}
接下来会调用 SimpleInstantiationStrategy#instantiate 。
org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.Object, java.lang.reflect.Method, java.lang.Object...)
通过反射, 设置 bean 的属性值, 进行 实例化.
如下:
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, final Method factoryMethod, Object... args) {try {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(factoryMethod);return null;});}else {ReflectionUtils.makeAccessible(factoryMethod);}// 重点看这里, 反射,进行实例化.// currentlyInvokedFactoryMethod 的类型是 ThreadLocal<Method> ,以此保证线程安全.Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();try {currentlyInvokedFactoryMethod.set(factoryMethod);// 通过反射, 设置 bean 的属性值Object result = factoryMethod.invoke(factoryBean, args);if (result == null) {result = new NullBean();}// 返回实例化的 bean.return result;}finally {if (priorInvokedFactoryMethod != null) {currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);}else {currentlyInvokedFactoryMethod.remove();}}}catch (IllegalArgumentException ex) {throw new BeanInstantiationException(factoryMethod,"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);}catch (IllegalAccessException ex) {throw new BeanInstantiationException(factoryMethod,"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);}catch (InvocationTargetException ex) {String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +"declaring the factory method as static for independence from its containing instance. " + msg;}throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());}}
CglibSubclassingInstantiationStrategy
CglibSubclassingInstantiationStrategy 实现了 SimpleInstantiationStrategy.
CglibSubclassingInstantiationStrategy 实例化 bean 的代码如下:
/*** 实例化, 动态生成*/public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {Class<?> subclass = createEnhancedSubclass(this.beanDefinition);Object instance;if (ctor == null) {instance = BeanUtils.instantiateClass(subclass);}else {try {// 实例化Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());instance = enhancedSubclassConstructor.newInstance(args);}catch (Exception ex) {throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);}}Factory factory = (Factory) instance;factory.setCallbacks(new Callback[] {NoOp.INSTANCE,new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});return instance;}相关文章:
Spring源码(八)--Spring实例化的策略
Spring实例化的策略有几种 ,可以看一下 InstantiationStrategy 相关的类。 UML 结构图 InstantiationStrategy的实现类有 SimpleInstantiationStrategy。 CglibSubclassingInstantiationStrategy 又继承了SimpleInstantiationStrategy。 InstantiationStrategy I…...
部署KVM虚拟化平台
文章目录 KVM虚拟化架构KVM组成KVM虚拟化三种模式 KVM虚拟化架构 KVM模块直接整合在Linux内核中 KVM组成 e KVM Driver虚拟机创建虚拟机内存分配虚拟CPU寄存器读写虚拟CPU运行 QEMU(快速仿真器) 模拟PC硬件的用户控件组件提供I/O设备模型及访问外设的途径 KVM虚拟化三种模式 客…...
Java对象模型深度剖析:从POJO到ENTITY
引言 在Java企业级应用开发中,对象模型是构建软件架构的核心。它们不仅帮助我们组织代码,还提升了代码的可读性和可维护性。本文将深入介绍Java中的几种关键对象模型:POJO、DTO、DAO、PO、BO、VO、QO和ENTITY,以及DO,…...
Nginx日志分析:编写Shell脚本进行全面日志统计
Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。无论是在大流量的网站还是小型的个人博客中,Nginx都得到了广泛应用。在实际生产环境中,对Nginx日志的分析有助于我们了解网站的访问情况,发现潜在问题…...
【Gin】深度解析:在Gin框架中优化应用程序流程的责任链设计模式(下)
【Gin】深度解析:在Gin框架中优化应用程序流程的责任链设计模式(下) 大家好 我是寸铁👊 【Gin】深度解析:在Gin框架中优化应用程序流程的责任链设计模式(下)✨ 喜欢的小伙伴可以点点关注 💝 前言 本次文章分为上下两部分…...
C语言——运算符及表达式
C语言——运算符及表达式 运算符运算符的分类(自增运算符)、--(自减运算符)赋值运算符逗号运算符(顺序求值运算符) 表达式 运算符 运算符的分类 C语言的运算符范围很宽,除了控制语句和输入输出…...
Python面试宝典第23题:分发糖果
题目 n 个孩子站成一排,给你一个整数数组 ratings 表示每个孩子的评分。你需要按照以下要求,给这些孩子分发糖果。 (1)每个孩子至少分配到 1 个糖果。 (2)相邻两个孩子评分更高的孩子会获得更多的糖果。 请…...
Java与模式及其应用场景知识点分享(电子版)
前言 Java 编程语言自1995年问世以来,其成功好像任何编程语言都无法媲美。生逢其时(互联网的兴起)固然是一方面的原因,而Java吸收总结了前人的经验教训,反映了最新技术(the state ofthe art),对其受到欢迎和采用,恐怕…...
软考高级第四版备考--第36天(审计内容)
IT内部控制审计:IT内部控制审计主要包括组织层面IT控制审计、IT一般控制审计及应用控制审计 IT专项审计:IT专项审计主要包括信息系统生命周期审计、信息系统开发过程审计、信息系统运行维护审计、网络与信息安全审计、信息系统项目审计、数据审计...
文件IO相关作业
1> 使用文件IO完成,将源文件中的所有内容进行加密(大写转小写、小写转大写)后写入目标文件中 源文件内容不变 #include<myhead.h>int main(int argc, const char *argv[]) {//判断传入的是否是两个文件if(argc!3){write(2,"inp…...
vue3 watch监听 父子组件通信
目录 01 watch监听方式 02 父子组件的通信 01 watch监听方式 1.watch(被监听的变量,(新值,旧值)>{ }) 默认直接就是深层监听 如果想要配置深度监听和默认触发 需要在第三个参数定义options对象 2.watch(被监听的变量,()>{},{ deep:true, immediate:true 项目打开后就执…...
【信创】adduser与useradd的区别 _ 统信 _ 麒麟 _ 中科方德
原文链接:【信创】adduser与useradd的区别 | 统信 | 麒麟 | 中科方德 Hello,大家好啊!今天给大家带来一篇关于在信创终端操作系统上adduser和useradd命令区别的文章。adduser和useradd都是用于在Linux系统上添加用户的命令,但它们…...
微软Win11 24H2最新可选更新补丁26100.1301来袭!
系统之家于7月31日发出最新报道,微软针对Win11 24H2用户推出七月最新的可选更新KB5040529,本次更新为开始菜单引入了全新的账号管理器,也改进了任务栏上的小组件图标。接下来跟随系统之家小编来看看本次更新的详细内容吧!【推荐下…...
层次特征的尺度艺术:sklearn中的缩放技术
层次特征的尺度艺术:sklearn中的缩放技术 在机器学习中,特征缩放(Feature Scaling)是数据预处理的重要步骤,尤其对于基于距离的算法,如K-近邻(KNN)和支持向量机(SVM&…...
Chapter 21 深入理解JSON
欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能! 文章目录 前言一、JSON数据格式1. 什么是JSON?2. JSON数据的格式 二、JSON格式数据转化三、格式化JSON数据的在线工具 前言 在当今数据驱动的世界中,JSON&…...
【C++高阶数据结构】红黑树:全面剖析与深度学习
目录 🚀 前言:红黑树与AVL树的比较一: 🔥 红黑树的概念二: 🔥 红黑树的性质 三: 🔥 红黑树节点的定义和结构🚀 3.1 基本元素🚀 3.2 节点颜色🚀 3.…...
前端基于 axios 实现批量任务调度管理器 demo
一、背景介绍 这是一个基于 axios 实现的批量任务调度管理器的 demo。它使用了axios、promise 等多种技术和原理来实现批量处理多个异步请求,并确保所有请求都能正确处理并报告其状态。 假设有一个场景:有一个任务列表,有单个任务的处理功能…...
Docker容器下面home assistant忘记账号密码怎么重置?
环境: docker ha 问题描述: Docker容器下面home assistant忘记账号密码怎么重置? 解决方案: 你可以按照以下步骤来找回或重置密码: 方法一 (未解决) 停止并删除当前的Home Assistant容器(确保你已经保…...
CTF-NSSCTF[GKCTF 2021]
[GKCTF 2021]easycms 考察: 用扫描工具扫描目录,扫描到后台登录界面/admin.php 题目提示了密码是五位弱口令,试了试弱口令admin和12345直接成功了 任意文件下载 点击设计-->主题然后随便选择一个主题,点击自定义࿰…...
MSA+抑郁症模型总结(一)(论文复现)
MSA抑郁症模型总结(一)(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 MSA抑郁症模型总结(一)(论文复现)情感分析在多场景的应用一、概述二、论文地址三、研究背景四…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
