Spring Bean的生命之舞:反射机制下的华丽转身

1. 引言

在Spring框架中,Bean的生命周期是一段复杂而精彩的旅程,其中反射机制扮演着举足轻重的角色。它不仅是Spring框架实现IoC(控制反转)和AOP(面向切面编程)等核心功能的基础,也是Bean实例化、属性赋值和初始化等过程的重要工具。本文将对Spring Bean生命周期中反射机制的应用进行深度讲解,并结合源码分析,揭示其背后的奥秘。


2. Spring Bean生命周期概述

Spring Bean的生命周期大致可以分为以下几个阶段:实例化、属性赋值、初始化、使用和销毁。在每个阶段,Spring都会利用反射机制来执行相应的操作。


3. 反射机制在Spring Bean生命周期中的应用

3.1 Bean的实例化

当Spring容器启动时,它会根据配置文件或注解中的信息,通过反射机制来实例化Bean。具体来说,Spring会调用Class.forName()方法加载Bean的类,并通过Class.newInstance()Constructor.newInstance()方法来创建Bean的实例。在Spring的源码中,这一过程主要由AbstractAutowireCapableBeanFactory类的createBeanInstance()方法实现。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {  // ...省略部分代码...  Class<?> beanClass = determineTargetType(beanName, mbd, registry);  // 使用反射机制实例化Bean  if (instanceSupplier != null) {  return obtainFromSupplier(instanceSupplier, beanName);  }  if (mbd.hasFactoryMethod()) {  return instantiateUsingFactoryMethod(beanName, mbd, args);  }  // 默认使用构造器实例化Bean  boolean resolved = false;  boolean autowireNecessary = false;  if (args == null) {  synchronized (mbd.constructorArgumentLock) {  if (mbd.resolvedConstructorOrFactoryMethod != null) {  resolved = true;  autowireNecessary = mbd.constructorArgumentsResolved;  }  }  }  if (resolved) {  if (autowireNecessary) {  return autowireConstructor(beanName, mbd, null, null);  }  else {  return instantiateBean(beanName, mbd);  }  }  // ...省略部分代码...  
}

3.2 属性的自动装配

在Bean实例化后,Spring会根据配置信息,通过反射机制将属性值注入到Bean中。这包括字段注入、构造函数注入和setter方法注入等方式。在源码中,这一过程主要由AbstractAutowireCapableBeanFactory类的populateBean()方法实现。该方法会遍历Bean的属性列表,并根据配置信息使用反射机制调用相应的setter方法或字段注入方法来完成属性赋值。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {  // ...省略部分代码...  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);  if (mbd.isSynthesized()) {  pvs = postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  }  if (needsDepCheck) {  checkDependencies(beanName, mbd, filteredPds, pvs);  }  if (pvs != null) {  applyPropertyValues(beanName, mbd, bw, pvs);  }  // ...省略部分代码...  
}

3.3 Bean的初始化

在Bean的属性赋值完成后,Spring会调用Bean的初始化方法来完成Bean的初始化操作。这个过程同样依赖于反射机制。如果Bean实现了InitializingBean接口或配置了init-method属性,Spring就会通过反射机制调用相应的初始化方法。在源码中,这一过程主要由AbstractAutowireCapableBeanFactory类的initializeBean()方法实现。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {  // ...省略部分代码...  if (mbd == null || !mbd.isSynthetic()) {  invokeAwareMethods(beanName, bean);  }  Object wrappedBean = bean;  if (mbd != null && !mbd.isExternallyManagedInitMethod("initMethod")) {  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  }  if (wrappedBean instanceof DisposableBean) {  // 注册销毁回调...  }  return wrappedBean;  
}

3.4 使用和销毁阶段

在Bean被使用的过程中,其状态可能会发生变化。当Spring容器关闭时,Spring会调用Bean的销毁方法(如果Bean实现了DisposableBean接口或配置了destroy-method属性)来释放资源。这个过程同样依赖于反射机制。


4. 总结

  • Spring Bean的生命周期中,反射机制发挥着至关重要的作用。从Bean的实例化、属性赋值到初始化和销毁,每个阶段都离不开反射的支持。通过深入理解Spring Bean生命周期中的反射机制,我们可以更好地掌握Spring框架的工作原理,从而更加高效地进行Spring项目的开发和优化。
  • 在Spring的源码中,我们可以看到大量使用反射机制的代码,这些代码实现了Bean的生命周期管理、依赖注入、AOP等功能。因此,熟练掌握反射机制并理解其在Spring框架中的应用是非常重要的。

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

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

相关文章

数组-下一个排列

一、题目描述 二、解题思路 1.反向遍历当前排列&#xff0c;比如 排列A[a,b,c,d,e,f...] &#xff0c;当遍历到e时&#xff0c;说明以 a,b,c,d,e为前缀的排列中不存在A排列的下一个排列。 2.把e&#xff08;位置设为idx&#xff09;和后面的元素作比较&#xff1a; 2.1 如果有…

在控制台看到 Docker 容器内部的输出

要在控制台看到 Docker 容器内部的输出&#xff0c;你可以使用以下几种方法&#xff1a; 使用 docker logs 命令&#xff1a; 这可以查看容器的标准输出和标准错误日志。 docker logs -f [CONTAINER ID]例如&#xff0c;对于你的容器&#xff0c;可以运行&#xff1a; docker l…

【数据结构(邓俊辉)学习笔记】二叉树02——遍历

文章目录 0.概述1. 先序遍历1.1 递归版1.1.1 实现1.1.2 时间复杂度1.1.3 问题 1.2 迭代版11.3 迭代版21.3.1 思路1.3.2 实现1.3.3 实例 2. 中序遍历2.1 递归形式2.2 迭代形式2.2.1 观察2.2.2 思路&#xff08;抽象总结&#xff09;2.2.3 构思 实现2.2.4 分摊分析 3. 后序遍历3…

网络原理 一

一、协议 网络通信中,协议是非常重要的概念. 协议进行了分层,此处就是按照这几层顺序来介绍每一层中的核心协议. 应用层,就对应着应用程序,是程序员打交道最多的一层,调用系统提供的 网络api 写出的代码都是基于应用层的. 应用层这里当然也有很多现成的协议,但更多的还是,程…

JVM(三)

在上一篇中&#xff0c;介绍了JVM组件中的类加载器&#xff0c;以及相关的双亲委派机制。这一篇主要介绍运行时的数据区域 JVM架构图&#xff1a; JDK1.8后的内存结构&#xff1a; (图片来源&#xff1a;https://github.com/Seazean/JavaNote) 而在运行时数据区域中&#…

Vivado报错集合

Synth 8-5535 报错代码 [Synth 8-5535] port <clk_0> has illegal connections. It is illegal to have a port connected to an input buffer and other components. The following are the port connections : Input Buffer:Port I of instance clkin1_ibufg(IBUF) i…

SwiftUI中List的样式及使用详解(添加、移动、删除、自定义滑动)

SwiftUI中的List可是个好东西&#xff0c;它用于显示可滚动列表的视图容器&#xff0c;类似于UITableView。在List中可以显示静态或动态的数据&#xff0c;并支持垂直滚动。List是一个数据驱动的视图&#xff0c;当数据发生变化时&#xff0c;列表会自动更新。 针对List&#x…

树莓派4B 有电但无法启动

试过多个SD卡&#xff0c;反复烧系统镜像都无法启动。接HDMI显示器没有信号输出&#xff0c;上电后PWR红灯长亮&#xff0c;ACT绿灯闪一下就不亮了&#xff0c;GPIO几个电源脚有电&#xff0c;芯片会发热&#xff0c;测量多个TP点电压好像都正常。 ……

华为造车布局全曝光,对标奔驰、迈巴赫等

文 | Auto芯球 作者 | 雷慢 这一刻&#xff0c;我承认我格局小了&#xff0c; 就在刚刚&#xff0c;余承东曝光了华为智选车的布局计划&#xff0c; 华为问界、智界、享界等&#xff0c;将全面对标奔驰、迈巴赫、劳斯莱斯等车系&#xff0c; 这布局&#xff0c;确实是世界…

揭秘《庆余年算法番外篇》:范闲如何使用维吉尼亚密码解密二皇子密信

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

Trino On K8S(Dockerfile)[建议]

文章目录 Trino On K8S&#xff08;Dockerfile&#xff09;[建议]前期准备基础镜像下载java构建 Dockerfile编写 bootstrap.sh 脚本构建镜像 部署 Trino下载 Helm 源修改配置启动 增加 Hive Catalog挂载 core-site.xml hdfs-site.xml 配置修改 coordinator/worker configmap修改…

Python开发Android手机APP

Kivy是一个开源的Python库&#xff0c;用于快速开发跨平台的触摸应用程序。它特别适合创建具有图形用户界面&#xff08;GUI&#xff09;的应用&#xff0c;尤其是那些需要在多种操作系统&#xff08;如Windows、macOS、Linux、Android和iOS&#xff09;上运行的多点触控应用。…

【yolov10】使用自己的数据集训练目标检测模型

【yolov10】使用自己的数据集训练目标检测模型 一、anaconda安装二、环境配置三、数据集制作1、labelimg的安装2、使用labelimg 四、正片1、下载yolov10源码2、数据集目录3、训练4、推理 一、anaconda安装 直接参考前一篇博客&#xff1a; https://blog.csdn.net/m0_71523511/…

42、Flink 关于窗口状态大小的考量

关于状态大小的考量 窗口可以被定义在很长的时间段上&#xff08;比如几天、几周或几个月&#xff09;并且积累下很大的状态&#xff0c;当估算窗口计算的储存需求时&#xff0c;注意如下&#xff1a; Flink 会为一个元素在它所属的每一个窗口中都创建一个副本。 因此&#x…

融捷科技(武汉)有限公司 面试总结/华润医药商业集团武汉有限公司武汉共享中心 软件开发面试总结/深圳市卓讯信息技术有限公司 软件开发面试总结

深圳市卓讯信息技术有限公司/Java高级/技术经理 自我介绍对方公司情况介绍最大的并发的项目介绍下为了解决并发做了哪些事情最熟悉的项目介绍下上千万的数据,如果通过身份证号码的后六位查询到对应条件的数据,要求在2秒内查询出结果。。。。。瞎扯淡部分融捷科技(武汉)有限…

击穿盲点——【网络安全】社会工程学中的网络欺骗

社会工程学起源于上世纪60年代左右&#xff0c;是一种通过人际交流的方式来获得情报的非技术渗透手段。这种手段无需过多技术要求&#xff0c;却非常有效&#xff0c;目前已成为危害企业网络安全的重大威胁之一。著名黑客凯文米特尼克在《反欺骗的艺术》中曾提到&#xff0c;人…

SpringBoot+Vue开发记录(七)-- 跨域文件与Restful风格

本篇文章的主要内容是关于项目的跨域配置和给项目添加restful风格接口。 重点是文件粘贴 文章目录 一、 跨域二、Restful风格1. 什么是restful风格&#xff1f;2. 项目文件结构3. 新建文件4. 在Controller中进行修改 一、 跨域 跨域问题暂时也就那样&#xff0c;解决方法就是…

云计算-No-SQL 数据库 (No-SQL Database)

DynamoDB简介 (Introduction to DynamoDB) AWS DynamoDB 是亚马逊提供的一种 NoSQL 数据库&#xff0c;适用于需要快速访问的大规模应用程序。NoSQL 数据库指的是非关系型数据库&#xff08;或许应该称为“非关系数据库”&#xff09;。关系型数据库是你之前可能使用过的熟悉的…

深入Django项目实战与最佳实践

title: 深入Django项目实战与最佳实践 date: 2024/5/19 21:41:38 updated: 2024/5/19 21:41:38 categories: 后端开发 tags: Django 基础项目实战最佳实践数据库配置静态文件部署高级特性 第一章&#xff1a;Django项目架构与设计原则 Django框架概述 Django是一个高级的P…