平时在开发程序的时候,每个对象在使用它的合作对象时都要自己主动去创建这个合作对象,需要时就主动创建出来,创建权在自己手里,但是这种方式耦合度就很高;在使用Spring之后,将对象的创建权交给Spring容器来处理,所谓的控制就是将对象创建控制权交给了容器来创建,即容器控制了对象的创建,起初依赖对象的创建时对象主动创建,是正转,而反转就是将依赖对象的创建及注入给Spirng容器处理,对象只是被动的接受依赖对象。
注入方式在IOC中,为被注入对象提供被依赖对象有三种方式:构造方法注入,setter注入,接口注入
DI(依赖注入)概念容器动态的将依赖关系注入到组件中,容器实例化对象的时候主动将它依赖的类注入给它
IOC的体系结构设计结构图
下面对结构图进行简要分析,来理解这个接口设计图
第一条接口设计主线是从BeanFactory到HierarchicalBeanFactory再到ConfigurableBeanFactory,BeanFactory定义了基本方法,例如getBean()等,HierarchicalBeanFactory增加了getParentBeanFactory接口功能,使BeanFactory具备了双亲IOC容器的管理功能;ConfigurableBeanFactory主要定义了一些对BeanFactory的配置功能,例如setParentBeanFactory()设置双亲IOC容器,通过addBeanPostProcessor()配置Bean后置管理器等;通过这些接口设计的叠加,定义了BeanFactory就是简单IOC容器的基本功能
第二条设计主线是以ApplicationContext为核心的接口设计,从BeanFactory到ListableBeanFactory再到ApplicationContext,再到我们常用的WebApplicationContext或者ConfigurableApplicationContext。L在这个接口体系中ListableBeanFactory和HierarchicalBeanFactory两个接口,连接BeanFactory接口定义和ApplicationContext应用上下文的接口定义。在ListableBeanFactory接口中,细化了许多BeanFactory接口功能,例如getBeanDefinitionNames()方法;对于ApplicationContext接口,它通过继承MessageSource,ResourceLoader,ApplicationEventPublisher,在BeanFactory简单IOC容器的基础上添加了许多对高级容器的特性支持。
Resource体系org.springframework.core.io.Resource,它的每一个实现类都代表了一周资源的访问策略,例如
ClassPathResource、RLResource、FileSystemResource 等。
ResourceLoader 体系
有了资源之后,就要对资源进行加载,Spring就是利用ResourceLoader来进行统一的资源加载
BeanFactory体系
BeanFactory提供的是最基本的IOC容器的功能,并且提供了IoC容器所应该遵守的最基本的服务契约;BeanFactory只是一个接口,而例如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContet等都可以提供具体的实现。
BeanFactory基本方法
- containsBean(String name)方法可以根据名字判断是否还有此名字的Bean
- isSingleton(String name)方法可以根据名字判断是否是单例的Bean
- isPrototype(String name)方法可以根据名字判断是否是多例的Bean
- isTypeMatch(String name, Class<?> typeToMatch)方法可以根据名字的Bean的Class类型是否是特定的Class类型
- getType(String name)方法查询指定名字的Bean的Class类型
- getAliases(String name)查询 该指定名字所有的Bean的别名
BeanFactory接口提供了使用IOC容器的基本接口规范,Spring还提供了符合这个IOC容器的一系列容器进行具体实现;通过XmlBeanFactory的实现为例进行说明:
从图中可以看到类之间的联系
从源码可知,XmlBeanFactory继承自DefaultListableBeanFactory,XmlBeanFactory新增了读取XML文件的方法
XmlBeanFactory就是通过这个方法进行xml读取,方法传参需要Resource做为参数进行传递,对xmlBeanDefinitionReader对象初始化,以及使用这个对象来完成对loadBeanDefinitions的调用
BeanDefinition体系用来描述Spring中的Bean对象。
BeanDefinitionReader体系
读取Spring配置文件内容,并将其转成IOC容器内部的数据结构:BeanDefinition
ApplicationContext体系
ApplicationContext除了能够提供前面介绍的容器的基本功能,还为用户提供了BeanFactory不具备的新特性
- 支持不同的信息源。ApplicationContext扩展了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现
- 访问资源:我们可以通过Resource来得到不同地方的Bean定义资源
- 支持应用事件:继承了接口ApplicationEventPublisher,从而在上下文中引入了事件机制
我们通过FileSystemXmlApplicationContext的实现为例来说明ApplicationContext的设计原理
FileSystemXmlApplicationContext有两个重要的功能
- 一个功能是应用直接使用FileSystemXmlApplicationContext,对于实例化这个应用上下文支持,同时启动IOC容器refresh()过程。这在FileSystemApplicationContext的代码实现中可以看到:
这个refresh()过程会涉及IOC容器启动的复杂操作,关于这个reresh()在IOC容器启动时的具体表现,在后面再进行详细分析
- 另一个功能是与怎样从文件系统中加载XML的Bean定义资源有关。
实现代码如下:
调用这个方法,可以得到FileSystemResource的资源定位
,