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抑郁症模型总结(一)(论文复现)情感分析在多场景的应用一、概述二、论文地址三、研究背景四…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...