目录
0.面向接口编程思想
面向接口编程:不针对实现编程,针对超类型编程。超类型包括继承和多态。而依赖倒置原则与好莱坞原则可以说是思想的具体体现,其表现形式便是控制反转,注入依赖则是控制反转的实现方式。其具体关系如下图1所示:

1.依赖倒置原则与好莱坞原则
1.1依赖倒置原则:
- 高层不应该依赖于低层,它们共同依赖于一个抽象;
- 抽象不能依赖于具象,具象依赖于抽象。
1.2好莱坞原则:
- (低层)别调用我们(高层),我们(高层)会调用你(低层)。
2.控制反转
在Spring中,框架和组件存在双向的强依赖关系:
一方面,在用户使用框架时,组件被动地响应框架的调用请求,即组件依赖框架。根据依赖倒置原则,应该在两个模块之间定义一个组件的抽象接口,高层(框架)调用组件抽象接口定义的函数,低层(组件)模块实现该接口,消解了从组件到框架之间的依赖关系。
另一方面,框架运行时,会主动调用组件,即框架依赖组件。根据好莱坞原则,应该在两个模块之间定义框架中一个模板方法的抽象接口,高层(框架)调用模板方法抽象接口定义的函数,低层(组件)模块实现该接口,消解了从框架到组件之间的依赖关系。
为什么说是控制反转了呢?因为不论是依赖倒置原则还是好莱坞原则,最终都是使框架主导一切,框架控制组件。也可以这样说,控制反转使得过去框架和组件之间双向的强依赖关系,变成单向的弱依赖关系(框架通过抽象控制组件)。
3.依赖注入
依赖注入是控制反转的具体实现方式。具体有三种形式:构造函数注入,接口注入和属性注入。下面我以构造函数注入为例,假设组件A在运行时需要组件B,如果没有控制反转的框架,那么:
这样我们会发现存在一些问题:
(1). 如果现在要改变 b生成方式,如需要用new B(String name)
初始化 b,需要修改 A 代码;
(2). 如果想测试不同 B对象对 A的影响很困难,因为 b的初始化被写死在了A的构造函数中;
但是我们如果利用IOC框架,在A的构造函数中注入B,那么IOC框架会这样做: 对象A依赖于对象B,当对象 A需要用到对象B的时候,IOC容器就会立即创建一个对象B送给对象A。IOC容器就是一个对象制造工厂,你需要什么,它会给你送去,你直接使用就行了,而再也不用去关心你所用的东西是如何制成的,也不用关心最后是怎么被销毁的,这一切全部由IOC容器包办。如下图所示:
4.Spring是如何实现依赖注入的?
当我们实现一个Bean之后,我们如何使其与Spring框架发生关系,即注入到Spring框架?这里我们不具体讲Bean的实现方式以及三种注入方式(构造函数注入、接口注入、方法参数注入和接口注入)。
对于前三种注入方式,我们都需要两步操作(以上面的组件A调用B为例):
- 解析A的XML文件,将其信息注册到Spring中;
- B在Spring中寻找解析好的A的信息;
第一步解析XML文件使用了Spring源码中的BeanFactory类,第二步使用了FactoryBean类。接下来的内容主要分这两块来介绍。
4.1 BeanFactory
BeanFactory主要的实现类是XmlBeanFactory。
1、在初始化XmlBeanFactory之前,需要通过ClassPathResource封装配置文件,这样才能进行后续的资源处理;
2、当配置文件被封装为Resource之后,Resource的加载工作就交给XmlBeanDefinitionReader中的reader.loadBeanDefinitions(resource)来处理了;
3、doLoadBeanDefinitions()才是真正的核心处理部分:
3.1、获取对XML文件的验证模式;
3.2、加载XML文件,并获得对应的Document;
3.3、根据返回的Document,解析及注册Bean信息,即BeanDefinitions。
这里我们主要介绍3.3,分为两块:解析BeanDefinitions以及注册BeanDefinitions。
3.3.1、解析BeanDefinitions:
(1)解析id以及name属性;
(2)进一步解析其他所有属性并统一封装至GenericBeanDefinition类型的实例中;(反射就是在这一步中完成)
(3)如果检测到bean没有指定beanName,那么使用默认规则为此bean生成beanName;
(4)将以上信息封装到BeanDefinitionHolder实例中。
3.3.2、注册BeanDefinitions:
(1)校验AbstractBeanDefinition;
(2)对beanName已经注册的情况的处理;
(3)通过Map将beanName与beanDefinition一一对应,即注册beanDefinition;
(4)清除解析之前留下的对应的beanName缓存。
4.2 FactoryBean
这里推荐看下郝佳写的《Spring源码深度解析》第五章,讲的非常好。
参考:
https://dotnetfresh.cnblogs.com/archive/2005/06/27/181878.html
https://www.cnblogs.com/sunzhao/p/8334008.html
https://www.jianshu.com/p/93246db67549
https://blog.youkuaiyun.com/qq_26323323/article/details/80968920