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;}

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

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

相关文章

SpringBoot通过3种方式实现AOP切面

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

Sonar-Scanner: 静态代码分析的利器

Sonar-Scanner: 静态代码分析的利器 懂得享受生活的过程&#xff0c;人生才会更有乐趣。每个人都会遇到一些陷阱&#xff0c;每个人都有过去&#xff0c;有的甚至是失败的往事。过去的错误和耻辱只能说明过去&#xff0c;真正能代表人一生的&#xff0c;是他现在和将来的作为。…

【更新2022】省级农民专业合作社数量 无缺失 2006-2022

省级农民专业合作社数量是研究中国农村经济组织和农业社会化服务的重要数据。这些数据可以用来分析不同省份农业生产组织形式的多样性及其对农民生产、技术创新和收入增长的影响。研究者可以基于这些数据&#xff0c;探讨农民专业合作社在提升农产品质量、优化农业生产结构和推…

Transformer处理文本分类实例(Pytorch)

文章目录 Transformer处理文本分类实例参考网站我们构建一个实例问题,预测AG_NEWS的文本分类AG_NEWS数据集介绍预测目标总体思路(简述)主要流程数据预处理dataset构建(不是重点)构建词表 编写处理模型执行词嵌入位置编码(PositionalEncoding)(*核心)多层Transformer模块多头自注…

Mojo数据类型详解

Mojo 中的所有值都分配有相对应的数据类型&#xff0c;大多数类型都是由结构体定义的标称的类型。这些类型是标称的&#xff08;或“命名的”&#xff09;&#xff0c;因为类型相等性是由类型的名称而不是其结构决定的。 有一些类型未定义为结构&#xff0c;例如下面的两种情况…

百款精选的HTML5小游戏源码,你可以下载并直接运行在你的小程序或者自己的网站上

今天我带来了一份特别的礼物——百款精选的HTML5小游戏源码&#xff0c;你可以下载并直接运行在你的小程序或者自己的网站上&#xff0c;只需双击index.html即可开始。无论你是在寻找创意引流&#xff0c;还是想为你的网站增添互动性&#xff0c;这些小游戏都能帮你实现&#x…

办公必备!一键把PDF转换为PPT文件,只需这3款神器!

在当今数字化办公环境中&#xff0c;文件格式的转换已成为提高工作效率的关键因素之一。其中&#xff0c;PDF(便携式文档格式)和PPT(PowerPoint演示文稿)是两种广泛使用的文件格式。然而&#xff0c;有时我们需要将PDF文件转换为PPT格式&#xff0c;以便进行编辑或演示。 为方…

数据结构的基本概念与算法

数据结构的基本概念与算法 什么是数据&#xff1f; 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合&#xff1b;总结来说 -> 数据就是计算机程序加工的原料&#xff1b; 数据元素、数据项&#xf…

<数据集>棉花识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;13765张 标注数量(xml文件个数)&#xff1a;13765 标注数量(txt文件个数)&#xff1a;13765 标注类别数&#xff1a;4 标注类别名称&#xff1a;[Partially opened, Fully opened boll, Defected boll, Flower] 序…

Java面试——Tomcat

优质博文&#xff1a;IT_BLOG_CN 一、Tomcat 顶层架构 Tomcat中最顶层的容器是Server&#xff0c;代表着整个服务器&#xff0c;从上图中可以看出&#xff0c;一个Server可以包含至少一个Service&#xff0c;用于具体提供服务。Service主要包含两个部分&#xff1a;Connector和…

SQL labs-SQL注入(七,sqlmap对于post传参方式的注入,2)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。参考&#xff1a;SQL注入之Header注入_sqlmap header注入-CSDN博客 序言&#xff1a; 本文主要讲解基于SQL labs靶场&#xff0c;sqlmap工具进行的post传参方式的SQL注入&#xff0c…

【Java版数据结构】初识泛型

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;Java版数据结构 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…

【全国大学生电子设计竞赛】2024年E题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

快速查找WGS1984 坐标地理坐标系转UTM投影坐标的多种方法

在arcgis中如果是要计算长度或面积&#xff0c;则需要将矢量图层地理坐标系转为投影坐标系&#xff0c;下面总结了几种快速找到“WGS 1984”&#xff08;UTM ZONE&#xff09;投影带号的方法。 一、准备工作 软件&#xff1a;arcmap 示例数据&#xff1a;安微省shp矢量图 二…

删除链表的倒数第N个结点(LeetCode)

题目 给你一个链表&#xff0c;删除链表的倒数第个结点&#xff0c;并且返回链表的头结点。 示例1&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例2&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例3&#xff1a; 输入&#xff1a;&#x…

申瓯通信设备有限公司在线录音管理系统(复现过程)

漏洞简介 申瓯通信设备有限公司在线录音管理系统 index.php接口处存在任意文件读取漏洞&#xff0c;恶意攻击者可能利用该漏洞读取服务器上的敏感文件&#xff0c;例如客户记录、财务数据或源代码&#xff0c;导致数据泄露 一.复现过程 fofa搜索语句:title"在线录音管…

【Vue3】标签的 ref 属性

【Vue3】标签的 ref 属性 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。…

Ubuntu22.04手动安装fabric release-2.5版本

这个过程稍微有点复杂&#xff0c;但完整操作完成以后会对Fabric网络有更加深入的理解&#xff0c;方便后续自己手动搭建Fabric网络。这个过程需要手动逐个下载Fabric源代码、使用命令下载Fabric镜像和用Git下载例子程序。 Fabric源代码主要用途是用来编译cryptogen、configtx…

二叉搜索树(图解)

文章目录 二叉搜索树的概念插入查找二叉搜索树的删除操作删除单孩子和叶子节点。del节点有两个孩子用左子树的最大节点替代用右子树的最小节点替代 弊端 二叉搜索树的概念 对于每颗子树&#xff0c;左子树 < 根&#xff0c;右子树 > 根。 二叉搜索树有以下操作&#xff1…

代码随想录二刷(哈希表)

代码随想录二刷(哈希表) 三数之和思路反正对于我来说是真的难想出来。 若这道题还是采用哈希表的思路去做&#xff0c;非常麻烦&#xff0c;并且还要考虑去重的操作。所以这道题其实用双指针&#xff0c;是更方便的。 具体程序如下&#xff1a; class Solution:def threeSu…