Spring IOC源码解读

Spring IOC源码解读

  • spring的Ioc概述
    • 一、ioc容器和依赖反转模式
    • 二、ioc容器系列
    • 三、Ioc系列容器的实现BeanFactory和ApplicationContext
      • 3.1 BeanFactory对IOC容器的功能定义
      • 3.2 Ioc容器的XmlBeanFactory的工作原理
      • 3.3 ApplicationContext的特点
      • 3.4 Ioc容器初始化
        • 3.4.1 BeanDefinition的Resource定位
        • 3.4.1 BeanDefinition在IoC中的注册
        • 3.4.2 IoC容器的依赖注入
      • 3.5容器的其他相关特性的实现
        • 3.5.1lazy_init属性和预实例化
        • 3.5.2FactoryBean的实现
        • 3.5.3BeanPostProcessor的实现
    • 四、spring对jdbc的支持
      • 4.1jdbcTemplate

spring的Ioc概述

一、ioc容器和依赖反转模式

通过ioc容器,对象依赖关系的管理被反转了,转到ioc容器中来了,对象之间的依赖关系由ioc容器进行管理。这里的反转,指的是责任的反转。

二、ioc容器系列

作为一个ioc容器,也需要为它的具体实现指定基本的功能规范,这个功能规范的设计表现为BeanFactory,它是spring为用户提供的ioc容器所设定的最基本的功能规范。

BeanDefinition来管理基于spring的应用中各种对象以及他们之间的相互依赖关系。它抽象了我们对Bean的定义,是让容器起作用的主要数据类型。这些BeanDefinition就像是水桶里的水。

三、Ioc系列容器的实现BeanFactory和ApplicationContext

3.1 BeanFactory对IOC容器的功能定义

我们要注意区分FactoryBean和BeanFactory,FactoryBean指的是工厂类实例化后的对象,而BeanFactory是生产类的工厂。

BeanFactory中的接口名单

  • containsBean
  • isSingleton,用户可以在BeanDefinition中指定
  • isPrototype,用户可以在BeanDefinition中指定
  • isTypeMatch
  • getType用来查询指定了名字的Bean的Class类型
  • getAliases根据别名查询,别名定义在了BeanDefinition中

3.2 Ioc容器的XmlBeanFactory的工作原理

这个BeanFactory提供了使用IOC的容器规范,在这个基础上spring提供了符合这个ioc容器接口的一系列的容器的实现供开发使用。BeanFactory的继承体系如下:AutowireCapableBeanFactory->AbstractAutowireCapableBeanFactory->DefaultListableBeanFactory->xmlBeanFactory。 XmlBeanFactory有一个明显的特征,就是他只提供最基本的IOC容器功能,可以读取Xml形式定义的BeanDefinition。BeanFactory是ioc容器的基本形式,而applicationContext实现是IOC容器的高级表现形式。

xmlBeanFactory在继承了DefaultListableBeanFactory容器的功能同时,给DefaultListableBeanFactory增加了一个与xml相关的BeanFactory,他可以读取以xml文件方式定义的BeanDefinition的一个ioc容器。

xmlBeanFactory如何实现读取XML文件定义的BeanDefinition呢?它初始化了一个XmlBeanDefinitionReader对象,有了这个对象就可以读取xml文件了。

在构造XmlBeanFactory这个IOC容器时,需要制定Bean、Definition的信息来源,这个来源需要封装成Spring中的Resource类。Resource是spring用来封装IO操作的类。比如我们的BeanDefinition信息是以xml文件形式存在的,那么可以使用像ClassPathResource res = new ClassPathResource(“bean.xml”);这样具体的ClassPathResource来构造需要的Resource。然后作为构造参数传递给XmlBeanFactory构造函数。这样IOc容器就可以方便的定位到需要BeanDefinition信息来对Bean完成容器化的初始化和依赖注入的过程。

如何编程式使用Ioc容器:

①ClassPathResource res = new ClassPathResource(“bean.xml”);

②DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

③XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

④reader.loadBeanDefinition(res);

①:创建IoC配置文件的抽象资源,这个抽象资源包含了BeanDefinition的定义信息。

②:创建一个BeanFactory,这里使用DefaultListableBeanFactory。

③:创建一个载入BeanDefinition的读取器,这里使用XMLBeanDefinitionReader来载入xml文件形式的BeanDefinition,通过一个回调配置给BeanFactory。

④:从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成。完成整个载入和注册Bean定义之后,需要的Ioc容器就建立起来了,这个时候Ioc容器就可以直接用了。

3.3 ApplicationContext的特点

ApplicationContext是一个高级形态意义的IoC容器。因为他继承了很多父类,拥有了很多父类的功能。

如:EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver(继承了ResourceLoader)。

  • 我们看到它扩展了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现,为开发多语言版本的应用提供服务。
  • 访问资源。体现在ResourceLoader和Resource的支持上,这样我们可以从不同的地方得到Bean定义资源。
  • 支持应用事件。继承了接口ApplicationEventPublisher,这样在上下文中引入了事件机制,这些事件和Bean的生命周期的结合为Bean的管理提供了便利。
  • ApplicationContext具备了丰富的附加功能,使得ApplicationContext与简单的BeanFactory相比,对它的使用是一种面向框架的使用风格,开发时一般使用建议使用ApplicationContext。

3.4 Ioc容器初始化

初始化过程包括:BeanDefinition的Resource定位、载入、注册这三个基本过程。

①定位:BeanDefinition的资源定位由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用提供了统一接口,比如文件系统中Bean定义信息可以使用FileSystemResource来进行抽象;在类路径中可以使用前面提到的ClassPathResource来使用。这个过程类似于寻找数据的过程。

②载入:BeanDefinition的载入,该载入过程把用户定义好的Bean表示成IoC容器的内部数据结构,而这个容器的内部的数据结构就是BeanDefinition。

③注册:向IoC容器注册这些BeanDefinition的过程,这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的。Ioc内部是使用一个HashMap来维持这些BeanDefinition数据的。

注意:Ioc容器和上下文初始化一般不包括Bean的依赖注入的实现。一般而言,依赖注入发生在应用第一次向容器通过getBean索取Bean时。但是有例外:ioc容器有一个预实例化的配置,可以通过在Bean定义信息中的lazyInit属性来设定,有了这个预实例化的配置,使得这个Bean的依赖注入在Ioc容器初始化时就预先完成了。

3.4.1 BeanDefinition的Resource定位

Spring IOC源码解读_第1张图片
画出spring定位时的代码流程图

3.4.1 BeanDefinition在IoC中的注册

注册的过程是发生在DefaultListableBeanFactory中的registerBeanDefinition方法中。填充到concurrentHashMap的definitionMap中

3.4.2 IoC容器的依赖注入

首先依赖注入是发生在用户第一次向Ioc索要bean时触发的,但是也有例外,如lazy_init属性可以完成对Bean的预实例化具体流程见流程图

3.5容器的其他相关特性的实现

3.5.1lazy_init属性和预实例化

预实例化时发生在AbstractApplicationContext中的refresh方法中实现的

Spring IOC源码解读_第2张图片
最后实在DefaultListableBeanFactory中的preInstantiateSingletons中实现的

3.5.2FactoryBean的实现

FactoryBean是一个能生产或修饰对象生成的工厂Bean。一个Bean如果实现了FactoryBean接口,那么根据该Bean的名称获取到的实际上是getObject()返回的对象,而不是这个Bean自身实例,如果要获取这个Bean自身实例,那么需要在名称前面加上’&'符号。

https://www.cnblogs.com/guitu18/p/11284894.html

3.5.3BeanPostProcessor的实现

四、spring对jdbc的支持

4.1jdbcTemplate

spring主要通过jdbcTemplate来操作数据库
Spring IOC源码解读_第3张图片spring与ibatis的结合,使用的是FactoryBean来完成对iBatis的配置,结合了Template来封装相应的操作

你可能感兴趣的:(java,Spring,java,spring)