只有光头才能变强
回顾前面:
在刷Spring书籍的时候花了点时间去学习了单例模式和工厂模式,总的来说还是非常值得的!
本来想的是刷完《Spring 实战 (第4版)》和《精通Spring4.x 企业应用开发实战》的IOC章节后来重新编写一篇IOC的文章的,看了一下之前已经写过的入门系列和。最主要的知识点都已经讲过了,所以感觉就没必要重新来编写这些知识点了...
我个人又不喜欢将写过的东西复制到新的文章中,所以建议大家可以先去阅读上面两篇文章再来看这篇(工厂模式那篇如果没有看过的同学也有必要去看看)~~
为了这篇文章知识点的完整性,重要的知识点(IOC概念理解,创建Bean、注入的三种方式等)还是会出现,但是不会将上面两篇博文的代码摘抄过来了。
这篇文章主要是补充和强化一些比较重要的知识点,并会把上面的两本书关于IOC的知识点整理出来并画成一个思维导图来全面了解Spring IOC的知识点!
那么接下来就开始吧,如果有错的地方希望能多多包涵,并不吝在评论区指正!
一、Spring IOC全面认知结合《Spring 实战 (第4版)》和《精通Spring4.x 企业应用开发实战》两本书的IOC章节将其知识点整理起来~
1.1IOC和DI概述在《精通Spring4.x 企业应用开发实战》中对IOC的定义是这样的:
IoC(Inversion of Control)控制反转,包含了两个方面:一、控制。二、反转
我们可以简单认为:
控制指的是:当前对象对内部成员的控制权。
反转指的是:这种控制权不由当前对象管理了,由其他(类,第三方容器)来管理。
IOC不够开门见山,于是Martin Fowler提出了DI(dependency injection)来替代IoC,即让调用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。
在《Spring 实战 (第4版)》中并没有提及到IOC,而是直接来说DI的:
通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定,对象无需自行创建或管理它们的依赖关系,依赖关系将被自动注入到需要它们的对象当中去
从书上我们也可以发现:IoC和DI的定义(区别)并不是如此容易就可以说得清楚的了。这里我就简单摘抄一下:
IoC(思想,设计模式)主要的实现方式有两种:依赖查找,依赖注入。
依赖注入是一种更可取的方式(实现的方式)
对我们而言,其实也没必要分得那么清,混合一谈也不影响我们的理解...
再通过昨天写过的,我们现在就可以很清楚的发现,其实所谓的IOC容器就是一个大工厂【第三方容器】(Spring实现的功能很强大!比我们自己手写的工厂要好很多)。
使用IOC的好处(知乎@Intopass的回答):
不用自己组装,拿来就用。
享受单例的好处,效率高,不浪费空间。
便于单元测试,方便切换mock组件。
便于进行AOP操作,对于使用者是透明的。
统一配置,便于修改。
参考资料:
https://www.zhihu.com/question/23277575--Spring IoC有什么好处呢?
1.2IOC容器的原理从上面就已经说了:IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。
原理就是通过Java的反射技术来实现的!通过反射我们可以获取类的所有信息(成员变量、类名等等等)!
再通过配置文件(xml)或者注解来描述类与类之间的关系
我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了!
上面描述的技术只要学过点Java的都能说出来,这一下子可能就会被面试官问倒了,我们简单来看看实际Spring IOC容器是怎么实现对象的创建和依赖的:
根据Bean配置信息在容器内部创建Bean定义注册表
根据注册表加载、实例化bean、建立Bean与Bean之间的依赖关系
将这些准备就绪的Bean放到Map缓存池中,等待应用程序调用
Spring容器(Bean工厂)可简单分成两种:
BeanFactory
这是最基础、面向Spring的
ApplicationContext
这是在BeanFactory基础之上,面向使用Spring框架的开发者。提供了一系列的功能!
几乎所有的应用场合都是使用ApplicationContext!
BeanFactory的继承体系:
ApplicationContext的继承体系:
其中在ApplicationContext子类中又有一个比较重要的:WebApplicationContext
专门为Web应用准备的
Web应用与Spring融合:
我们看看BeanFactory的生命周期:
接下来我们再看看ApplicationContext的生命周期:
初始化的过程都是比较长,我们可以分类来对其进行解析:
Bean自身的方法:如调用 Bean 构造函数实例化 Bean,调用 Setter 设置 Bean 的属性值以及通过
Bean级生命周期接口方法:如 BeanNameAware、 BeanFactoryAware、 InitializingBean 和 DisposableBean,这些接口方法由 Bean 类直接实现;