前言

  Spring源码继承结构比较复杂,看过以后经常会忘记。因此,记录一下源码分析的过程,方便以后回顾。本次分析的Spring源码版本为3.2.15。

  另外,一提Spring就是IOC、DI等等,我们先初步了解一下这些概念。

依赖倒置原则(Dependence Inversion Principle):面向对象设计原则的一种(抽象概念),其他的还有单一职责原则、里氏替换原则、接口隔离原则、依赖倒置原则、迪米特原则、开-闭原则。

控制反转(Inversion Of Control):它是遵循依赖倒置原则设计的一种设计模式或者说设计思想(还是停留在概念),所谓控制反转其实就是依赖对象的获取权被反转了,不再由自己控制,而是由第三方来控制。

依赖注入(Dependency Injection):依赖注入是实现控制反转(设计思想)的一种具体实现方式。

依赖倒置原则(DIP)

依赖倒置原则
A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
 
举个简单例子理解一下:
public class ServiceA{
private ServiceB serviceB;//ServiceB是一个接口 public void toDoMethod(){
serviceB.toDo();
} public ServiceA(){
this.serviceB=new ServiceBImpl1();
}
}
什么是高层次的模块依赖于低层次的模块?
  ServiceA需要调用ServiceB的服务,在ServiceA的构造方法里创建了ServiceB的实现ServiceBImpl1,这就是高层次模块(ServiceA)依赖了底层模块(依赖了具体实现:ServiceBImpl1),这种依赖就有个问题,如果调用ServiceA是根据不同场景需要调用ServiceB不同的实现怎么办呢?所以这种依赖具体实现的方式就导致ServiceA与ServiceB的具体实现耦合太高,ServiceA没法做成一个通用组件。
public class ServiceA{
private ServiceB serviceB;//ServiceB是一个接口 public void toDoMethod(){
serviceB.toDo();
}
}

什么是依赖倒置呢?

  如上代码所示,ServiceA中并没有ServiceB具体实现,也就是所谓的ServiceA依赖了ServiceB的抽象。在编译期ServiceA(.高层次的模块)并没有依赖低层次模块(ServiceB的具体实现),只有真正在运行期需要ServiceB实现的时候才会有交集,这就大大降低耦合度。

控制反转(Inversion Of Control)

依赖倒置原则只是告诉我们不要依赖具体实现,要依赖抽象。它只是指导思想,具体怎么去实现呢?控制反转就是在指导思想下设计出的一套解决方案。

高层次模块中只依赖低层次模块的抽象(接口或抽象类),创建低层次模块具体对象的事情不再由高层次模块负责,而是交由第三方来完成,在运行期需要的时候再通过某种方式获得低层次模块的实现。

到此,还是只停留在理论层面。

依赖注入(Dependency Injection)

IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:<1>依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这种方式。<2>依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor Injection)三种方式。

依赖注入是现在最主流的方式。因为它太主流,导致现在ioc已经约等于DI。

IOC容器

我们提到创建依赖对象的工作由第三方来完成,这个第三方就是IOC容器,它负责理清模块与模块直接的依赖关系,并且负责进行依赖注入。

当然,这个容器要做的足够灵活、可配置。

总结

依赖倒置是指导思想

    反转控制是解决方案

        依赖注入是一种具体实施

IOC的优点:

  1.模块与模块直接耦合度降低,这样有利于团队协作开发、单元测试。

  2.面向接口编程,系统灵活性增加。

  3.模块直接的复杂依赖关系、对象的创建以及生命周期管理等都有容器完成。

IOC的缺点:

  1.原本简单通过new就可以完成的对象创建,现在需要一个复杂过程来完成。

  2.面向接口编程,灵活度增强了必然导致效率的降低。

所以说,IOC这种模式不是适合所有的系统,还是要根据系统特点来选择是否需要IOC模式。

Spring源码解析(一)开篇的更多相关文章

  1. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  2. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...

  3. spring 源码解析

    1. [文件] spring源码.txt ~ 15B     下载(167) ? 1 springн┤┬вио╬Ш: 2. [文件] spring源码分析之AOP.txt ~ 15KB     下载( ...

  4. Spring源码解析——循环依赖的解决方案

    一.前言 承接<Spring源码解析--创建bean>.<Spring源码解析--创建bean的实例>,我们今天接着聊聊,循环依赖的解决方案,即创建bean的ObjectFac ...

  5. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  6. Spring源码解析之PropertyPlaceholderHelper(占位符解析器)

    Spring源码解析之PropertyPlaceholderHelper(占位符解析器) https://blog.csdn.net/weixin_39471249/article/details/7 ...

  7. Spring源码解析之BeanFactoryPostProcessor(三)

    在上一章中笔者介绍了refresh()的<1>处是如何获取beanFactory对象,下面我们要来学习refresh()方法的<2>处是如何调用invokeBeanFactor ...

  8. Spring源码解析之ConfigurationClassPostProcessor(二)

    上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...

  9. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

随机推荐

  1. mui区域滚动条

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 数论 - SGU 107 987654321 problem

    987654321 problem Problem's Link Mean: 略 analyse: 这道题目是道简单题. 不过的确要好好想一下: 通过简单的搜索可以知道,在N<9时答案一定为0, ...

  3. JavaScript的gzip静态压缩方法记录

    传统的JS压缩(删除注释,删除多余空格等)提供的压缩率有时还是不尽不意,幸亏现在的浏览器都支持压缩传输(通过设置http header的Content-Encoding=gzip),可以通过服务器的配 ...

  4. C++标准库之mutex

    互斥锁有可重入.不可重入之分.C++标准库中用mutex表示不可重入的互斥锁,用recursive_mutex表示可重入的互斥锁.为这两个类增加根据时间来阻塞线程的能力,就又有了两个新的互斥锁:tim ...

  5. 通用性能测试过程模型GAME(A)

    1.3.1  Goal(定义目标) 制定一个明确而详细的测试目标是性能测试开始的第一步,也是性能测试成功的关键. 本步骤的开始时间:需求获取阶段 本步骤的输入:性能需求意向 本步骤的输出:明确的性能测 ...

  6. Asp.net - Razor - 将Model中变量的值赋值给Javascript变量

    <script type="text/javascript"> @{var _userID = Model.UserId.HasValue ? Model.UserId ...

  7. 设置Android程序图标和程序标题

    修改程序名称 在/res/values/strings.xml中修改程序名称,例如: <string name="app_name">你的程序名称</string ...

  8. 苹果使用蓝汛CDN网络分发ios8

        2014年9月18日凌晨,苹果公司公布了全新的ios8系统正式版.不出所料的引发了空前高涨的"果粉"下载热潮.引爆整个苹果界.     ios8被业内称为"自Ap ...

  9. 面试题思考:解释一下什么叫AOP(面向切面编程)

    这种在运行时,动态地将代码切入到类的指定方法.指定位置上的编程思想就是面向切面的编程. AOP是Spring提供的关键特性之一.AOP即面向切面编程,是OOP编程的有效补充. 使用AOP技术,可以将一 ...

  10. Linux网络流量控制工具—Netem

    第一篇:概念篇 Netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块.该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带宽.传输延迟.丢包等等情况.使 ...