Spring ioc容器设计与实现

IOC容器概念

ioc容器用来管理bean的创建对象,依赖注入,装配以及bean的生命周期。

IOC容器的分类

  • beanfactory 简单的ioc容器,只提供ioc容器基本的特性

  • applicationContext 面向高级的ioc容器,在beanfactory的基础上增添了很多面向框架的高级特性。
    Spring ioc容器设计与实现_第1张图片

    上图是springioc容器设计的主要接口,主要分为两大路径,分别对应上面简单的ioc容器以及高级的ioc容器

  1. 从接口beanfactory到HierarchicalBeanFactory再到ConfigurableBeanFactory 是一条主要的beanfactory的设计路径,在这个设计路径中beanfactory定义了基本的ioc容器的规范。
    Spring ioc容器设计与实现_第2张图片
    包括获取beangetBean,是否包含beancontainsBean,是否单例isSingleton,是否类型匹配isTypeMatch,获取bean的classgetType,获取别名getAliases等。
    而HierarchicalBeanFactory主要是增加了getParentBeanFactory接口,使得bean具有了双亲ioc容器的管理功能。
    HierarchicalBeanFactory
    ConfigurableBeanFactory主要定义了对beanfactory的配置功能,如设置双亲IOC容器setCurrentlyInCreation,配置bean后置处理器addBeanPostProcessor等。
    通过如上接口设计的叠加,就完成了一个ioc容器的基本功能。
    Spring ioc容器设计与实现_第3张图片

  2. 第二条线路主要是以ApplicationContext应用上下文接口为核心的接口设计,主要是从BeanFactoryListableBeanFactory再到ApplicationContext再到我们熟悉的WebApplicationContextConfigurableApplicationContext
    Spring ioc容器设计与实现_第4张图片
    上面是一张ApplicationContext接口的设计,同时继承ListableBeanFactoryListableBeanFactory,这样就链接了ApplicationContext接口和BeanFactory接口的结合,同时ApplicationContext接口还继承了ResourceLoader接口,以及ApplicationEventPublisher接口,这样使得Application拥有了资源定位以及事件发布的高级特性。
    Spring ioc容器设计与实现_第5张图片
    上图是ListableBeanFactory接口结构,可以看到获取bena名称BeanDefinitionName及其他获取方式。
    综合:这个接口系统是以beanFactory和Application这两个为核心的,BeanFactory是ioc容器的基本容器,Application则是通过继承beanFactory体系的ListableBeanFactory等接口来实现ioc的基本容器,同时又继承了MessageSource,ResourceLoader和ApplicationEventPublisher来为Application赋予更加高级的特性。

IOC容器的设计原理

Spring ioc容器设计与实现_第6张图片
我们以xmlBeanFactory为例子来说明ioc容器的设计原理,首先看到xmlBeanFactory就可以看出他是一个跟XMl有关的BeanFactory接口的具体实现,
他继承于DefaultListableBeanFactory这个类。
下面我们来看下DefaultListableBeanFactory这个类
Spring ioc容器设计与实现_第7张图片
DefaultListableBeanFactory是一个基本的标准的IOC容器实现,他实现了基本ioc容器所具有的重要功能。事实上在Spring中DefaultListableBeanFactory是一个默认的功能完整的ioc容器来使用,比如ApplicationContext的实现中我们都可以看到DefaultListableBeanFactory的身影,这个不多做介绍 大致按照这个路线可以找到
AbstractApplicationContext#refresh()->AbstractApplicationContext#obtainFreshBeanFactory()->AbstractRefreshableApplicationContext#refreshBeanFactory()->AbstractRefreshableApplicationContext#createBeanFactory()

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }
    }
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);
        }
        ............   
    }
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

 protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            ...
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
    }

总结起来大致就是,Spring为我们提供了一个基础的完整的IOC容器,在设计高级IOC容器也就是ApplicationContext的时候,可以直接使用这个现成的功能完整的基础IOC容器,并在其基础上做一些定制化的改造,如Resource的定位,不同的ApplicationContext实现自己对应的Resource诸如ClassPathResource,FileSystemResource,ServletContextResource等等。。

我们可以如下编程式的使用IOC容器

ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(resource);

在进行IOC容器的设计上我们可以针对以上各个组建进行定制化的改造,如resource资源的定位,beanFactory的实现,BeanDefinitionReader的读取转换实现等等。。

总结

看懂ioc容器设计的第一步我觉的下面的这张接口图很重要,可以帮助理清ioc容器的设计思路。

Spring ioc容器设计与实现_第8张图片

你可能感兴趣的:(Spring)