一个Spring微型Ioc容器的分析

前言:之前看过<<Spring技术内幕>>有关IOC容器的讲解,无奈Spring的容器实现挺复杂,也没看懂。前几天无意中在git hub上看到了一个模仿Spring的IOC容器实现:tiny-ioc,麻雀虽小可五脏俱全,实现了Spring IOC基本功能,对把握Spring容器的设计大有裨益。自己也跟着作者一步一步实现,基本上对Spring IOC有了一个整体上的把握,具体的实现细节还是要去看源码。今天来对前面一段的学习做个总结。

1.目录结构

2.文件说明

(1)围绕Resource的类主要解决的是容器的内容从哪里读取,也就是配置文件从哪里读、如何读取的问题。

类名 说明
Resource 接口,资源标识,通过getInputStream()方法获取外部资源输入流。
UrlResource Resource接口的一个实现,通过URL获取资源。
ResourceLoader 资源加载类,通过getResource(String)方法获取Resource对象。

(2)围绕BeanDefinition的类主要解决的是Bean的定义问题。包括Bean的名字、属性、类型等,即如何在容器中定义一个Bean,并根据这个定义生成实例。

类名 说明
BeanDefinition 这个类保存了Bean的定义,包括Bean的名字beanClassName,类型beanClass,属性propertyValues。propertyValues是一个PropertyValue的列表,PropertyValue包含了一个属性名name,和一个属性值Object。如果Object的类型为BeanReference类型,则表明引用了另一个Bean,需要替换为实际类型。
BeanDefinitionReader 接口,定义了加载BeanDefinition的规范,loadBeanDefinitions(String)。
AbstractBeanDefinitionReader 实现BeanDefinitionReader接口,规定了BeanDefintionReader的基本结构。拥有一个HashMap register,用于保存String-Defintion键值对。拥有一个ReourceLoader,用于保存资源加载器。使用时只需向loadBeanDefintions()方法传入一个资源地址,就可以调用资源加载器解析Bean定义,并将解析到的BeanDefinition保存到register中。
XmlBeanDefintionReader 具体实现AbstractBeanDefinition,从xml中读取Bean定义。

(3)围绕BeanFactory的类主要解决的是如何实例化和装备Bean的问题。

类名 说明
BeanFactory 接口,标识一个容易,通过getBean(String)方法获取Bean实例。
AbstractBeanFactory BeanFactory接口的抽象实现类,规范容器的基本结构,并将如何实例化Bean交给子类实现,这里用到了设计模式中的模板模式。用一个<String, BeanDefinition>的beanDefintionMap来维护Bean定义。当从容器中获取Bean时,如果在容器中存在就返回,如果不存在则调用doCreateBean实例化一个。
AutowireCapableBeanfactory 实现自动装配的BeanFactory。首先根据BeanDefinition中的beanClassName生成一个类实例,并将其保存在BeanDefintion中(这里是提前暴露Bean,防止属性循环依赖无法完成注入的问题),接着给这个Bean设置属性。设置属性时,遍历BeanDefinition中的PropertyValues,根据PropertyValue的name将属性值设置到对应字段,如果属性值为BeanReference类型则需要调用getBean(String)从容器中获取依赖的Bean,再进行注入。

(4)围绕ApplicationContext的类主要是将ResourceLoader、BeanDefinitionReader、BeanFactory的gon功能进行了封装,给外部提供一个统一的根据资源路径获取Bean的方法。

扫描二维码关注公众号,回复: 5639825 查看本文章
类名 说明
ApplicationContext 接口,继承了BeanFactory,因此标识为一个容器。BeanFactory实现了如何实例化和装配Bean,并没有说明BeanDefiniton是如何加载的。这个接口将BeanFactory和BeanDefintionReader结合在了一起。
AbstractApplicationContext 实现了ApplicationContext接口,规范了子类的基本结构。拥有一个BeanFactory类型的属性,getBean(String)方法的具体工作委托给BeanFactory的getBean(String)方法实现。refresh()方法规定了从哪里获取资源加载类定义,这个委托给子类实现。
ClassPathXmlApplicationContext 从类路径加载资源。通过XmlDefinitionReader解析UrlResourceLoader读取到的Resource,获取BeanDefiniton后,保存到BeanFactory。

3.涉及的设计模式

这里的BeanFactory、BeanDefinitionReader、以及ApplicationContext都用到了模板模式。这里以BeanFactory为例,AbstractBeanFactory这个抽象类并没有实现doCreateBean这个方法,而是把这个方法交给不同的子类去实现。

猜你喜欢

转载自blog.csdn.net/qq_22866497/article/details/88775803