(一)Spring IOC容器的设计与实现
控制反转
Spring IoC的IoC全称是"Inversion of Control",译:控制反转
"控制反转"又称"依赖反转"
DI全称是"Dependency Injection",译:依赖注入
使用控制反转,依赖注入后,当创建对象时,由一个调度系统将其所依赖的对象的引用传递给它(这些对象也都来自于调度系统所管理的对象),即依赖被注入到对象中。所以,控制反转是关于一个对象如何获取它所依赖的对象的引用
上述的调度系统是应用平台,具体来说是IoC容器。通过使用IoC容器,对象依赖关系的管理被反转了,转到IoC容器中来了,对象之间的相互依赖关系由IoC容器进行管理,并由IoC容器完成对象的注入
IoC容器的核心数据结构
BeanDefinition是IoC容器的核心数据结构。又称"Bean定义信息"。是创建Bean实例时所使用的模板
Bean是容器管理的对象的统称
容器在创建Bean实例之前会先创建BeanDefinition对象,它保存了Bean的定义信息,例如Bean的名字,类型,是单实例还是多实例,是不是懒加载,所依赖的其他对象有哪些等
IoC容器的设计与实现
IoC容器有两个系列
一个是实现BeanFactory接口的简单容器系列,这个系列的容器能实现容器的最基本的功能。又称"Bean工厂"
一个是实现ApplicationContext接口的高级容器系列,它是容器的高级形态。又称"应用上下文"或"上下文"。上下文在简单容器的基础上又增加了许多新功能
Spring IoC容器的设计
下面这张图描述的IoC容器的接口设计图,IoC容器的实现类就是以容器的接口设计为基础实现的

设计主线
- 以
BeanFactory为核心。从BeanFactory到HierarchicalBeanFactory再到ConfigurableBeanFactory。这是一条主要的BeanFactory类型容器的设计路线 - 以
ApplicationContext为核心。从BeanFactory到ListableBeanFactory到ApplicationContext,再到ConfigurableApplicationContext或WebApplicationContext。我们常用的上下文基本都是ConfigurableApplicationContext或WebApplicationContext的实现类
我们常用的BeanFactory的实现类是DefaultListableBeanFactory。同时,以这个实现类为基础,又有许多应用于不同场景下的子类bean工厂。不过我们通常直接使用DefaultListableBeanFactory
我们常用的ApplicationContext的实现类是AbstractApplicationContext的子类。这个抽象类包含了容器的初始化方法refresh()。
AbstractApplicationContext实现的是ConfigurableApplicationContext接口。
BeanFactory的设计原理
这些接口方法定义出了一个基本的IoC容器

boolean containsBean(String name);容器中是否有名为name的BeanString[] getAliases(String name);查询Bean的所有别名getBean()有多个重载方法,是从容器中获取Bean实例的方法(此方法包含如果获取不到就创建一个Bean实例的流程)boolean isSingleton(String name);返回Bean是否是单实例boolean isPrototype(String name)返回Bean是否是多实例(Bean是单实例还是多实例,这些信息保存在对应的BeanDefinition对象中)- ...
这些方法提供了容器最基本的功能
ApplicationContext的设计原理
ApplicationContext除了实现了BeanFactory外还实现了其他接口,为容器添加了其他功能

MessageSource信息源。支持国际化功能的实现ResourceLoader访问资源。用于获取Bean的定义信息所在的资源,为创建BeanDefinition对象做准备ApplicationEventPublisher发布事件。可以在上下文中,在Bean的生命周期中发布事件- ...
容器初始化流程
首先,由编码者使用某种形式编写Bean的配置信息,例如在.xml文件中写标签配置Bean
然后,启动容器进行初始化。容器初始化大致分三步
BeanDefinition的Resource定位(定位Bean配置信息所在位置)- 载入
BeanDefinition(创建BeanDefinition对象) - 向容器注册
BeanDefinition对象(在容器内部将对象put到一个容器持有的map对象中)
在第一次调用容器的getBean()方法(BeanFactory中定义的方法)获取Bean对象时,如果对象还未被实例化,就获取对应的BeanDefinition对象,并使用它作为模板创建实例对象
再容器完成初始化后,调用refresh()方法刷新容器。方法执行完后容器便可以使用
ps:容器初始化的流程可能在refresh()方法外执行,也可能在refresh()方法内执行
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
