Spring源码--IOC容器的实现步骤

Spring IOC(控制反转)与DI (依赖注入)

IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。
Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。

IoC和DI的关系,其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“ 依赖注入” 明确描述了“被注入对象依赖IoC 容器配置依赖对象”

Spring Bean的加载过程

  • 容器的初始化做了几件事情:
  1. 资源的定位,就是定位你配置的xml文件
  2. 对resource文件进行解析,解析成spring 定义的BeanDefinition
  3. 对BeanDefinition 进行注册,其实就相当于把BeanDefinition 放到一个CurrentHashMap
  • 依赖的注入:
  1. 根据BeanDefinition创建Bean实例
  2. 为Bean注入依赖的实例

下面是流程

这个接口体系是以BeanFactoryApplicationContext为核心的。BeanFactory是IOC容器的最基本的接口,ApplicationContext一方面继承了BeanFactory体系的:ListableBeanFactory和HierachicalBeanFactory,具备了BeanFactory IOC容器的基本功能,另一方面,又通过继承MessageSource、ResourcePatternResource、EnvironmentCapable、ApplicationEventPublisher这些接口,拥有了更高级的IOC容器特性。

项目中Spring的过程

首先Web项目使用Spring是通过在web.xml里面配置org.springframework.web.context.ContextLoaderListener初始化IOC容器的

ContextLoaderListener继承了ContextLoader,并且实现ServletContextListener接口。当Server容器(一般指tomcat)启动时,会收到事件初始化。initWebApplicationContext方法是在org.springframework.web.context.ContextLoader类里面,它做了几件事情:首先是判断servletContext中是否已经注册了WebApplicationContext,如果有则抛出异常,避免重复注册。然后就是启用log,启动计时。接着进行了一系列复杂的东西, 将ServletContext设置成XmlWebApplicationContext的属性,这样就可以通过XmlWebApplicationContext读取web.xml中配置的spring文件,然后就是进行上面的IOC容器的实例化及bean的注入。

上面对于Spring的几个图和简单说明还是可以看的,不过Spring的源码读起来不是那么好看,这里给大家一个建议:沿主线把代码跟一遍,再回头去看辅助代码。因为Spring是一个很成熟的框架了,它在编码过程中要考虑的问题很多,比如IOC容器启动,我们只需要知道它是如何定位Resource,如何解析BeanDefinition,如何注册。那么在这个过程中,会有很多的基于安全、性能、扩展等等的考虑,加上Spring运用了很多的设计模式,也就产生了很多的我们眼中的冗余、不知道干啥的代码。所以,前几遍读源码,要能抛开这些代码跟着主线代码一直看下去,等你把这个过程搞清楚了,再回头去看一些前面的辅助代码。

猜你喜欢

转载自kuanghe.iteye.com/blog/2383052