零:认识BeanDefinitionjava
在面向对象程序设计中,咱们以"对象"来做为问题空间与解空间中一对一映射关系的抽象。BeanDefinition类就是ioc容器中,对依赖反转模式中管理的对象之间依赖关系的数据抽象,简单来讲:它抽象了spring对Bean的定义,用来管理基于spring的应用中的各类对象,以及对象之间的相互依赖关系。spring
一:BeanFactory接口清单app
BeanFactory定义了IOC容器的最基本形式,提供了IOC容器应该遵循的最基本服务契约。ide
getBean 方法是ioc容器的主要方法,能够获取ioc容器中管理的Beanspa
containsBean 判断容器中是否含有指定name的bean设计
isSinglton 查询指定name的bean是否为单例模式code
isPrototype 查询指定name的bean是否为原型模式(多实例)xml
(isSinglton和isPrototype能够在BeanDefinition中经过setScope来指定)对象
isTypeMatch 查询指定name的Bean的class类型是否与特定的class类型匹配继承
getType 查询指定name的bean的class类型
getAliases 查询指定name的Bean的全部别名(返回string[]),别名能够经过BeanDefinition定义
-----------------------------------------------------------------------------------------------------
二:XmlBeanFactory
XmlBeanFactory是一个能够读取以xml文件方式定义的BeanDefinition的ioc容器
在xmlBeanFactory中初始化一个XmlBeanDefinitionReader对象,用它来处理以xml方式定义的BeanDefinition,xmlBeanFactory并不直接参与处理。
xmlBeanFactory的构造器中,咱们能够看到Resourse对象,Resourse对象是spring用来封装io操做的类,在此它为xmlBeanFactory指定了XmlBeanDefinitionReader的信息来源。
XmlBeanFactory继承自DefaultListableBeanFactory,spring把DefaultListableBeanFactory做为一个默认的功能完整的ioc容器来使用,它实际包含了基本ioc容器所具备的重要功能。xmlBeanFactory在其基础上扩展出了处理xml信息的方法。
从这个咱们能够看到ioc容器使用的基本过程应该是:
1:建立ioc配置文件的抽象资源。(包含BeanDefinition)
2:建立一个BeanFactory。
3:建立一个载入BeanDefinition的读取器(如XmlBeanDefinitionReader),并经过回调配置给BeanFactory。
4:讲定义好的资源位置读入配置信息,具体的解析过程由具体的读取器来完成。完成载入和注册bean信息后,就能够经过ioc容器直接使用了。
-----------------------------------------------------------------------------------------------------
三:ApplicationContext
ApplicationContext在BeanFactory的基础上添加了更多功能,能够说是一个高级形态的ioc容器,也是咱们最经常使用的。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {...}
ApplicationContext增长的特性:
1:支持不一样的信息源。从上面代码中能够看到,ApplicationContext扩展了MessageSource接口,这些信息源的扩展功能能够支持国际化的实现,为开发多语言版本应用提供服务。
2:访问资源。咱们能够从不一样的地方获得Bean定义资源,尤为是从不一样的I/O途径得到Bean的定义信息。这一特性体如今对ResourceLoader和Resource的支持上。(ApplicationContext接口的实现类都继承了DefaultResourceLoader)
3:支持应用事件。继承ApplicationEventPublisher接口,该接口在上下文中引入了事件机制,为Bean的管理提供便利。
4:其余附加的服务。
ApplicationContext容器的设计原理
咱们在研究applicationContext设计原理时,以实现类FileSystemXmlApplicationContext为例。
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {...}
上图能够看到:FileSystemXmlApplicationContext中只包含了与它自身设计相关的两项功能,而其余功能都已经由他的父类AbstractXmlApplicationContext实现了。
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
第一个功能:在FileSystemXmlApplicationContext的构造器中,调用了启动ioc容器的refresh() 方法,这个方法牵扯到ioc容器启动的一系列复杂动做,同时,对于不一样的容器实现这些动做都是相似的,因此在基类(AbstractApplicationContext)中将他们封装好,此处仅进行调用。
@Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }
另外一个功能:实现了从文件系统中加载xml的Bean定义资源。这部分是他设计的具体相关内容。经过他能够为读取xml文件上保存的BeanDefinition作准备(仅是作准备,并不是直接处理,由于不一样的应用上下文实现对应着不一样的读取beanDefinition方式),此处仅获得FileSystemResourse定位资源。
总结:
1:顶层(相对顶层)接口定义通用契约
2:其余分支接口对顶层契约进行扩展,
3:用抽象类实现接口,对接口方法进行部分实现(也可所有实现,根据需求判断)。此时,若这个抽象类的具备多个子类,则能够把子类间存在分歧的部分写成抽象方法。而多个子类中相同的部分则集中由这个抽象类来进行实现。(若是仅仅只有一个子类,那么并不须要抽象类来对接口进行过滤,能够直接用一个类来实现接口,可是考虑到系统扩展的可能性,仍然建议这样作。)
4:抽象类的子类,仅仅定义与其功能设计相关的部分,但并不对相关功能进行实现,实现功能的动做被分配到其余执行者中。(由于可能会有多种不一样的执行者)