依赖控制反转的实现很多方式,在spring中IOC容器是实现这个模式的载体,他可以在对象生成或初始化直接将数据注入
到对象中,也可以通过将对象引用主导数据域中的方式来注入方法调用的依赖。这种依赖注入可以是递归的,对象被逐层注入。
这种方案有一种完整而简介的美感,他把对象的依赖关系有序的建立起来,简化了对象依赖关系的管理,在很大程度上简化了面向对象的复杂性。
在spring IOC容器设计中,有两个主要的容器系列,一个是实现BeanFactory 接口的简单容器系列,这个鞋脸容器只实
了容器最基本的功能;另一个是ApplicationContext应用上下文,他作为容器高级形态而存在。ApplicationContext在简单的容器基础上,增加了许多面向框架特性,同时对应用环境做了许多适配。
spring 通过定义BeanDefinition来管理基于spring的应用中各种对象已经他们之间互相依赖关系,BeanDefinition
抽象了我们的主要数据类型。IOC 容器来说,BeanDefinition 就是对依赖反转模式管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能核心数据结构,依赖反转功能都是围绕BeanDefinition的处理完成的。
BeanFactory接口定义了基本的IOC 容器的规范,在这个接口定义中,包括了getBean()这样的IOC容器基本方法,通过这个方法可以从容器中取得Bean,HierarchicalBeanFactory接口在继承了BeanFactory的基本接口之后,增加getParentBeanFactory()的接口功能,是BeanFactory具备了双亲IOC容器管理功能
以 ApplicationContext应用上下接口为核心的接口设计,这里涉及的主要接口设计有,从BeanFactory到ListableBeanFactory,再到ApplicationContext,再到我们使用的FileSystemXmlApplication 或 WebAppLicationContext 接口,我们常用的上下文基本都是 ConfigurableApplicationContext 的实现。ListableBeanFactory接口中细化了许多BeanFactory的接口功能比如定义了getBeanDefinitionNames()接口方法;对于ApplicationContext 接口他通过继承MessageSource ResourceLoader ApplicationEventPublisher 接口,在BeanFactory简单IOC容器的基础上添加许多高级容器的特性支持。而具体的IOC容器都是在这个接口体系下实现的,比如DefaultListableBeanFactory这个基本IOC容器的实现就是实现了ConfigurableBeanFactory,从而成为IOC容器的实现。像其他IOC容器,比如XmlBeanFactory 都是在DefaultListableBeanFactory的基础上做拓展,同样的ApplicationContext 的实现也是如此。
BeanFactory 接口代码:
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
这里有一系列的接口方法,通过这一系列的BeanFactory接口,可以使用不同的Bean的检索方法,很方便从IOC容器中的到需要的bean,从而忽略具体
IOC容器的实现,这些检索方法代表的是最为基本的容器入口
在spring 中,DefaultListableBeanFactory 作为一个默认的功能完整的IOC容器来使用,XmlBeanFactory 在继承了DefaultListableBeanFactory
容器的功能同时,增加了新的功能,这些工能很容易从XmlBeanFactory的名字上猜的到,他是一个与XML 相关的BeanFactory,也就是说他是可以读取XML 文件方式定义
的BeanDefinition 的IOC容器。
对于这些XML 文件定义信息的处理并不是由XmlBeanFactory直接完成,在内部初始化了一个XmlBeanDefinitionReader对象,有了这个Reader 对象那些以XML方式定义的BeanDefinition就有了处理方式。构造XmlBeanFactory这个ico容器时,需要制定BeanDefinition的信息来源,而这个信息来源需要封装成Spring中的resource 类给出,resource 是Spring IO 操作的类。
XmlBeanFactory 接口代码
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
在XmlBeanFactory 构造方法中需要得到resource对象,对XmlBeanDefinitionReader 对象的初始化,以及使用这个对象来完成对loadBeanDefinitions的调用,就是这个调用启动重resource中载入BeanDefinition的过程,loadBeanDefinitions 同时也是ico容器初始化重要部分。其实整个流程我们自己也可以自定义自己的factory
ClassPathResource resource = new ClassPathResource(“bean.xml”);
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
接下来就可以使用这个factory了
在 使用ioc容器时候需要如下几个步骤:
1,创建IOC配置文件的抽象资源,这个抽象资源包含了BeanDefinition 的定义信息
2,创建BeanFactory这里使用了DefaultListableBeanFactory
3,创建一个一个载入BeanDefinition的读取器,这里使用了XmlBeanDefinitionReader来载入XML文件形式的BeanDefinition,通过一个回调配置给BeanFactory
4,从定义好的资源位置读取配置,具体的解析交给XmlBeanDefinitionReader来完成。