当前位置: 首页 > news >正文

Spring源码系列:依赖注入(四)-总结

  • Spring源码系列:依赖注入(一)getBean
  • Spring源码系列:依赖注入(二)createBean
  • Spring源码系列:依赖注入(三)-属性注入

在上面三篇文章中对依赖注入做了一个大致的梳理;里面都是大量代码的分析,本文在此基础上进行一个总结归纳。

依赖注入调用过程

如前几篇文章所述,依赖注入是由getBean来触发的;然后涉及到bean实例的创建、依赖关系的建立、属性注入等子过程。

  • getBean 方法触发依赖注入
  • doGetBean 从容器中查找Bean(BeanFactory链,当前容器->双亲容器-双亲容器...)

当然,在获取到某个Bean的时候也会通过递归的方式来依赖注入依赖的bean

  • createBeanInstance 生成了Bean所包含的Java对象,Spring中用SimpleInstantiationStrategy类来生成Bean对象的实例,实例化Java对象的方法有两种(CGlib是默认方式):

    • 通过BeanUtils,它使用了JVM的反射功能来生成Java对象实例
    • 用CGLIB来生成,CGLIB是一种常用的字节码生成器的类库
  • populateBean 设置Bean对象的依赖关系

  • resolveValueIfNecessary 注入类型的处理;解析不同类型的属性

  • setPropertyValues 属性注入

关于lazy-init

Ioc容器的初始化过程中,主要的工作就是对BeanDefinition的定位、载入、解析和注册;但是就像之前说过的,此时依赖注入还没有发生。在Spring源码系列:依赖注入(一)getBean文中提到,依赖注入发生在应用第一次向容器获取Bean的时候;也就是上面说到的通过getBean来触发。

当然,依赖注入也可以在容器初始化的过程中就完成。这个就是lazy-init属性的存在意义了。就是说我们可以通过设置Bean的lazy-init属性来控制预实例化的过程。

预实例化:在初始化容器时完成Bean的依赖注入

这种做法的好处在于提高了我们第一次获取Bean的的效率,但是它也降低了容器初始化的速度。(这个其实很好理解的,因为第一次获取Bean的时候,依赖注入已经完成了,直接拿过来用就行)

关于lazy-init属性的处理也是在wac.refresh这个方法中完成的,具体是在finishBeanFactoryInitialization方法中。如果继续追溯的话,最终是交给DefaultListableBeanFactory容器中的preInstantiateSingletons方法中完成。

lazy-init这种实例化方式就是通过将依赖注入委托给容器来处理,而不是在用户第一向容器申请的Bean的时候完成依赖注入,不同的阶段,也有不同的优劣。

相关文章:

  • react native android 真机调试
  • WeexConf 2018干货系列|Weex + Ui
  • CSS最常用的三种选择器
  • GridView中使用CheckBox
  • 使用Python读写csv文件的三种方法
  • jdk动态代理使用及原理
  • mariadb/mysql使用Navicat连接报错
  • 【10】万魂杀服务器开发之特性 条件触发器(Condition Trigger)机制
  • 【Lv1-Lesson007】Where Are You From?
  • 写一个H5___type:range__调色板
  • React 组件生命周期
  • STL的注意事项
  • hdu 4857 Little Devil I
  • Spring Boot实践--项目打包、启动、关闭的方法
  • centos7 安装 gitolite (git服务器)
  • angular学习第一篇-----环境搭建
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Consul Config 使用Git做版本控制的实现
  • DataBase in Android
  • docker容器内的网络抓包
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • node入门
  • PAT A1120
  • spring + angular 实现导出excel
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 构建二叉树进行数值数组的去重及优化
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 数据仓库的几种建模方法
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​Linux·i2c驱动架构​
  • #DBA杂记1
  • #前后端分离# 头条发布系统
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (1)Android开发优化---------UI优化
  • (11)MSP430F5529 定时器B
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (三)elasticsearch 源码之启动流程分析
  • (十五)使用Nexus创建Maven私服
  • (十一)c52学习之旅-动态数码管
  • (新)网络工程师考点串讲与真题详解
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net 生成二级域名
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .net下的富文本编辑器FCKeditor的配置方法
  • .NET学习教程二——.net基础定义+VS常用设置
  • .NET值类型变量“活”在哪?
  • /deep/和 >>>以及 ::v-deep 三者的区别