前言:这是在慕课网上学习剑指Java面试-Offer直通车时所做的笔记

目录

第一章 IOC原理

第二章 SpringIOC的应用

2.1 BeanFactory

2.2 ApplicationContext

第三章 SpringIOC的refresh源码解析

第四章 SpringIOC的getBean方法的解析

第五章 小的知识点

5.1 SpringBean的作用域

5.2 创建过程

5.3 销毁过程


第一章 IOC原理

IOC(Inversion of control) :控制反转

IOC可以说是Spring最核心的部分,是Spring家族任意组件的基本,IOC本身并不能算为一种技术而是一种思想,它使你从繁琐的对象交互中解脱出来,进而专注于对象本身,更进一步突出面向对象,要了解控制反转,要先了解一个软件设计的重要思想即依赖注入.

举例:

设计行李箱

不用依赖注入:

本身的代码:上层建筑依赖下层建筑

现在我们要修改轮子的大小

用依赖注入:

修改轮子的大小:

这种设计模式还有利于协同合作和单元测试.

比如上述四个模块是由四个小队开发的,只要定义好了接口,四个小队可以同时开发而不相互受到限制.

测试Luggage时只要mock Framework类传入Luggae就行了.不用把其余三个类全部new一遍了.

上述这种以DI实现的IOC给我们带了很大的编译,其实DI还有DL的实现方式,会在需要的时候调用框架提供的方法来获取Bean,现在DL已经被抛弃了.DI是当今IOC的主流实现.

依赖注入的方式:

Setter: 实现特定属性的public Setter方法,来让IOC容器调用注入所依赖类型的对象.

Interface: 实现特定的接口以供IOC容器注入所依赖类型的对象.

Constructor: 实现特定参数的构造函数,在创建对象时来让IOC注入所依赖的对象.

Annotation: 通过Java的注解机制,来让IOC容器注入所依赖类型的对象.(Autowired)

依赖导倒置原则,IOC,DI,IOC容器之间的关系

依赖倒置原则是一种思想,高层模块不应该依赖于底层模块.两者都应依赖其抽象.正是依赖倒置原则的指导,才有了IOC的思路,实现IOC离不开DI,Spring框架基于IOC才提出了容器的概念,对于IOC来说最重要的就是容器.容器管理着Bean的声明周期和容器的依赖注入.

那什么是IOC Container呢?

下面的代码就是IOC容器所做的事情了.

容器可以自动对代码进行初始化,开发者只需维护一个Configuration.

IOC要求我们的class要有配置文件,这样我们实例化对象时不用一个一个的去看构造函数,IOC会自动根据配置进行创建.

第二章 SpringIOC的应用

Spring启动时去读取应用程序提供的Bean配置信息,并在Spring容器中生成相应的Bean定义注册表,然后根据注册表去实例化Bean,装配好Bean之间的依赖关系,为上层提供准备就绪的运行环境.

Spring提供一个配置文件描述Bean与Bean之间的依赖关系,利用Java语言的反射功能实例化Bean,并建立Bean之间的依赖关系.

SpringIOC容器的核心接口

2.1 BeanFactory

核心接口:

BeanDefinition:主要用来描述Bean的定义,Spring在启动时会将Xml或者注解里Bean的定义解析成Spring内部的BeanDefinition.

BeanDefinitionRegistry:提供向IOC容器注册BeanDefinition对象的方法.

举例:新建SpringBoot的项目

registerBeanDefinition方法主要是将BeanDefinition注册到BeanFactory接口的实现类DefaultListableBeanFacory中的beanDefinitionMap中,Spring将Bean的定义解析成Definition之后会通过DefinitionRegistry以BeanName为key,BeanDefinition为value存储到BeanDefinitionMap里面,同时将BeanName存储到beanDfinitionNames里,以便后序Bean的实例化.

BeanFactory是Spring框架最核心的接口,能将Bean从客户端的配置中解放出来,其的主要作用为:

提供了IOC的配置机制

BeanFactory包含Bean的各种定义,以便实例化Bean.

在实例化时建立Bean之间的依赖关系.

Bean生命周期的控制.

其的主要的结构图为:

ListableBeanFactory该接口定义了访问容器中Bean的若干方法,如查看Bean的个数,获取某一类型Bean的配置名,查看容器中是否包括某一Bean等方法.

HierarchicalBeanFactory是父子级联的IOC容器接口,子容器可以通过接口方法访问父容器,通过HierarchicalBeanFactory接口SpringIOC可以建立父子层级关联的IOC层级体系,子容器可以访问父容器的Bean,父容器不能访问子容器的Bean,比如展现层的Bean位于子容器中而业务层和持久层的Bean位于父容器的Bean.

ConfigurableBeanFactory:增强了IOC接口的可定制性,定义了设置类装载器,属性遍历器,以及属性初始化后置处理器等方法.

AutowireCapableBeanFactory:定义了将容器中的Bean按某种规则,按名字匹配,按类型匹配等.

SingletonBeanRegistry:允许在运行期间向容器注册SingletonBean实例的方法.

通过这些接口也证明了BeanFactory的体系也确实提供了IOC的基础及依赖注入和Bean的装载等功能.

代码实例:

打开BeanFactory可以看到多个getBean方法, 这也是Spring容器最重要的方法之一, 从Spring容器中获取Bean,可以按类型名称获取Bean,isSingleton判断Bean是否是单例,.

2.2 ApplicationContext

由于BeanFactory的功能还不够强大,于是Spring在BeanFactory的基础上还设计了一个更为高级的接口即ApplicationContext,它是BeanFactory的子接口之一.在我们使用SpringIOC容器时,大部分都是context的实现类.

终极结构图:

代码实例:

点进run方法中,层层递进,逢run就点

点到有很多代码的地方,往下翻就会找到如下,发现会根据类型去加载AplicationContext,会通过Class.forname去加载...WebServerAppliacationContext

第三章 SpringIOC的refresh源码解析

首先和之前一样,点进SpringApplication的run方法中,层层往下点,直到点到如下为止

将代码拖动到如下位置,createApplicationContext我们刚才讲过是依据不同的配置加载不同的ApplicationContext

再往下最核心的是refreshContext方法,点进去可以看到如下,前端是refresh,调用了AbstractApplicationContext中的refresh方法,

prepareRefresh:完成配置之类的解析,设置Spring的状态,初始化属性源信息,验证环境信息中必须存在的属性.

ConfigurableListableBeanFactory是用来获取beanFactory的实例的.

prepareBeanFactory:对beanFactory进行相关的设置,为后续的使用做准备,包括设置classLoader用来加载Bean,设置表达式解析器等等.

postProcessBeanFactory:是用于在BeanFactory设置之后进行后续的BeanFactory的操作.

invokeBeanFactoryPostProcessors:点进去发现调用了如下方法,点进去之后发现逻辑相当复杂,主要调用工厂后处理器,调用Bean标签,扫描Bean文件,并解析成一个个的Bean,这时候这些Bean是被加载进了Spirng容器当中

,这里涉及了各种类,我们在这里主要讲解一下ConfigurationClassParser.主要是解析Bean的类.该方法会对带有@configuration,@import,@bean,以及@SpringBootApplication等标签的Bean进行解析,

registerBeanPostProcessors:会从Spring容器中找出实现BeanPostProcessors接口的Bean,并设置到BeanFactory的属性之中,之后Bean实例化时会调用BeanProcessor,也就是Bean的后置处理器.会和AOP比较相关.

initMessageSource:初始化国

initApplicationEventMuticaster:初始化事件广播器

onRefresh:是一个模板方法,不同的Spring容器会重写它做不同的事情.比如web程序的容器,会调用create..方法去创建内置的servlet容器.

registerListeners:注册事件监听器

finishBeanFactoryInitialization:会实例化BeanFactory中已被注册但未被实例化的所有实例,懒加载是不需要被实例化的.前面的invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的Bean在这个时候都会被初始化,同时初始化过程中的各种PostProcessor就会开始起作用了.

finishRefresh:会做初始化生命周期处理器相关的事情.

后面是注册钩子,这钩子是希望开发者能结合自己的实际需求扩展出一些在Spring容器关闭时的行为.

再往下我们可以看到afterRefresh方法,它的方法体是空的, 也就说明Spring框架考虑了扩展性,留了很多的口子,让大家在框架层面继承很多的模块并去做自定义的实现.

第四章 SpringIOC的getBean方法的解析

getBean方法用来加载Bean,我们发现所有的getBean都最终会调用doGetBean方法,点击进去

我们打上断点运行项目,发现确实会调用doGetBean来实例化Bean,首先通过transformedBeanName提取出BeanName的名字,获取到BeanName后会根据singleton方法获取一个共享的实例,这个实例可能是Bean的实例也有可能是一些工厂的实例,获取到这些实例后就会调用getObjectForBeanInstance方法,去试着从缓存或者实例工厂中去获取实例,如果getSingleton获取不到的话,它就会尝试从parentBeanFactory中去获取.

然后会将父类的属性与子类的属性进行合并.注意dependsOn不等于空,如果存在依赖,就要递归去实例化依赖存在的Bean,

判断Bean的作用域是否是singleton,如果是就看先前是否创建过,如果有的话直接返回,如果没有就创建一个,如果作用于是protype,就new一个出来,如果是其它范围会按照else的范围创建.

第五章 小的知识点

5.1 SpringBean的作用域

5.2 创建过程

实例化bean和其属性,容器管理的Bean一般不需要了解容器,这时就需要设置对容器的感知,可以通过Aware接口完成.紧接着调用BeanPostProcessor前置初始化方法,在Spring完成实例化之后对Spring实例化后的Bean添加一些自定义的处理逻辑,然后经过一些过程,再调用BeanPostProcessor的后置初始化方法.去做一些Bean实例初始化后的自定义工作与AOP相关

5.3 销毁过程

SpringIOC的初步理解相关推荐

  1. 如何让人大致理解RxJava思想:第一节 初步理解RxJava

    如何让人大致理解RxJava思想:第一节 初步理解RxJava 首先,我们需要明确,一个人不可能一口气吃成一个胖子,你不可能仅仅花5分钟看完我这篇文章,然后一拍桌子,大叫一声,我知道了,然后赢取白富美 ...

  2. JAVA 枚举类的初步理解

    JAVA 枚举类的初步理解 现在Java的枚举类在真实项目中已经用的比较频繁,比静态常量更好用,也更有限定性,enum类可以用来表示有限的类对象,比如星期.月份.性别或者项目中的产品类型 像诸如此类的 ...

  3. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感...

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  4. 初步理解pagerank算法

    初步理解pagerank算法 第一次写不是课程要求的博客,可能有不严谨的地方,如果有写错的希望能在评论区指出. 算法思想 pagerank算法用于网页排序,根据给网页的重要程度给各个网页打分,根据分数 ...

  5. Adaboost算法的初步理解

    菜鸟初次接触Adaboost,虽然算法流程比较清晰简单,但对于其中的理论,存在着不少疑惑之处,如下所示: 1)如何训练得到的弱分类器,我们需要训练出多少个弱分类器进行后续的计算?对若分类器有什么要求吗 ...

  6. 我对SNS游戏的初步理解

    国庆期间,我专门研究了一款SNS游戏,巴别小精灵,这是一款背单词的游戏.算是一款交互式英语学习的应用.一点初步理解和体会,与大家分享. SNS游戏的特点 (1)      异步性 (2)      真 ...

  7. Hamiltonian Monte Carlo抽样算法的初步理解

    Hamiltonian Monte Carlo抽样算法的初步理解 接受拒绝采样算法 MCMC回顾 Hamiltonian dynamics 拉格朗日方程 从牛顿方程出发推导拉格朗日方程 勒让德变换 哈 ...

  8. 红黑树插入操作的初步理解

    红黑树插入操作的初步理解 文章目录 红黑树插入操作的初步理解 红黑树的特征 红黑树的插入节点总是红色的 红黑树的修正 变色 左旋 右旋 插入操作 插入操作的代码实现 红黑树和AVL树的对比 参考链接 ...

  9. wmts格式说明_WMTS服务初步理解与读取

    WMTS 服务初步理解与读取 当前在网络地图服务中,大部分都会采取缓存技术来替代实时对数据进行可视化,用以提高地图响应能 力.介绍 OGC 提出的缓存技术标准的 WMTS 服务. WMTS 简介 WM ...

最新文章

  1. 从 StarCraft 2 Installer.exe 中提取种子文件
  2. 使用Axis2创建一个简单的WebService服务
  3. jQuery.ajax实现根据不同的Content-Type做出不同的响应
  4. s71200模拟量输入输出_模拟用户输入并检查输出的简单方法
  5. matlab中 %s 是什么意思,ie在matlab中是什么意思
  6. linux降低eigen3版本_玩转 Windows 自带的 Linux 子系统 (图文指南)
  7. Exchange Server2010系列之三:Exchange Server部署完成后的配置
  8. spring boot连接redis配置127.0.0.1_springboot+redis项目实战
  9. 【开源】多多客发布 3.0.0-alpha.6,Koa+Vue+Taro最佳实践
  10. 「leetcode」 1382. 将二叉搜索树变平衡:【构造平衡二叉搜索树】详解
  11. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查...
  12. 如何从头开始使用Python实现堆栈泛化(Stacking)
  13. PSCAD v4.21-ISO
  14. C语言编译程序的顺序,C语言函数定义顺序
  15. Trimble Sketchup Pro 2013 英文破解版
  16. 与美不期而遇:Carry on Till Tomorrow
  17. 中软酒店管理系统CSHIS操作手册_数据结构_数据字典
  18. android rfid开发实例,Android NFC读卡 高频卡 RFID
  19. “progtam received signal SIGABRT,Aborted.“错误
  20. 个人秋招面经——商汤

热门文章

  1. HTTP的四种请求方式
  2. eclipse配置Tomcat
  3. jq实现轮播图(景深效果)——功能实现
  4. 硬盘录像机开机无显示
  5. TimePicker,SharedPreferences实现android小闹钟
  6. 仅用Excel就可玩转逻辑回归?!
  7. tp的think-queue的队列使用
  8. Cannot add PPA: ‘ppa:~jonathonf/ubuntu/vim‘. ERROR: ‘~jonathonf‘ user or team does not exist.解决方法
  9. 互联网资讯:小红书8月2日正式推行“号店一体”机制,支持“0门槛快速开店”
  10. 关于Oracle数据库删除表空间后磁盘空间不释放的问题