Spring源码阅读之-BeanFactory(一)

(http://blog.csdn.net/weiythi/article/details/74194083)
控制反转——spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
部分参考资料:《控制反转(IoC)与依赖注入(DI)》 博主写的不错,简单易懂。
以上这一段摘自[《Spring源码分析(一)-Spring环境的初始化》]
Spring实现IOC和DI的最主要的核心就是BeanFactory了

BeanFactory

BeanFactory实际上是实例化,配置和管理众多bean的容器。 这些bean通常会彼此合作,因而它们之间会产生依赖。 BeanFactory使用的配置数据可以反映这些依赖关系中 (一些依赖可能不像配置数据一样可见,而是在运行期作为bean之间程序交互的函数)。
一个BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示, 这个接口有多个实现。 最常使用的的简单的BeanFactory实现是org.springframework.beans.factory.support.DefaultListableBeanFactory(这里注意一下,好多文章说的是:org.springframework.beans.factory.xml.XmlBeanFactory)这个类已经被(@deprecated as of Spring 3.1 in favor of {@link DefaultListableBeanFactory})
这里写图片描述

通过查看DefaultListableBeanFactory的类图,我们可以看到其庞大的类家族,这里有几个分支。
1.BeanFactory
2.BeanDefinitonRegistry
3.SingletonBeanRegistry

其中BeanDefinitonRegistry在之前的文章中已有少数说明,BeanFactory位于类结构树的顶端,其主要的方法就是getBean,即通过BeanName获取到由BeanFactory管理的Bean实例
BeanFactory的功能通过其子接口得到不断的扩展,其主要的几个
- ListableBeanFactory:定义了访问容器中bean的基本信息的若干方法,如查看bean的个数,获取某一类型bean的配置名称,或者查看容器中是否包含某一bean等等这些方法。
- HierarhicalBeanFactory:父子级联IoC容器的接口,子容器可以通过接口方法访问父容器。
- ConfigurableBeanFactory:增强了IoC容器的可定制性。他定义了设置类装载器、属性编辑器、容器初始化后置处理器等等方法。
- AutowireCapableBeanFactory:将容器中的bean按照某种规则比如:按照名称匹配,按照类型匹配等等来进行自动装配的方法。
- SingletonBeanFactory:在容器运行期间向容器注册单实例bean的方法
- BeanDefinitionRegistry:Spring配置文件中,每一个bean节点元素在Spring容器里面都通过一个BeanDefinition对象来表示,他描述了Bean的配置信息。BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法。

BeanFactory 的方法定义(markdown贴html代码片好像做不到,截个图吧):
这里写图片描述
有的时候在线文档更简单易懂,还能离IDE的线,自行学习。其实看其定义的方法,通过其方法的描述很容易看懂其功能,BeanFactory定义的若干方法中,出现最多的既是getBean,可见BeanFactory的主要功能都是围绕Bean展开的,是否有Bean,获得Bean的别名,根据名称获取bean,根据类型获取bean,bean是多例的还是单例的。
那么BeanFactory的实现类是如何维护Bean的呢,刚刚说道最常用的BeanFactory的实现就是DefaultListableBeanFactory,如果想先了解Bean是如何被取出的,那么需要先知道Bean是如何被注册到容器中的,还好我们之前已经通过几篇文章分析了Spring解析bean定义的流程,其最后是通过以下代码完成注册的。

/**
     * Process the given bean element, parsing the bean definition
     * and registering it with the registry.
     */
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
                //使用工具类注册Bean
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

BeanDefinitionReaderUtils.registerBeanDefinition 源码如下

/**
     * Register the given bean definition with the given bean factory.
     * @param definitionHolder the bean definition including name and aliases
     * @param registry the bean factory to register with
     * @throws BeanDefinitionStoreException if registration failed
     */
    public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // Register bean definition under primary name.
        // 获取beanName
        String beanName = definitionHolder.getBeanName();
        // 注册Bean的定义
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        // 注册BeanName对应的别名
        // Register aliases for bean name, if any.
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }

我们通过之前贴出的UML图和以前的文章,可知DefaultListableBeanFactory本身就是一个BeanDefinitionRegistry,如ctrl+alt+b图所示:
这里写图片描述

根据《Spring源码阅读之-bean的解析与注册》 中得出的总结,注册到BeanFactory中的是一个BeanDefinition对象,暂且不去探究其代码层面上是如何维护BeanDefinition的(想想看,beanName需要对应BeanDefinition,类内部维护这样的关系肯定是一个Map结构),但是注册BeanDefinition只是AbstractApplicationContext类中refresh执行的众多操作的一环,其在registerBeanDefinition方法中并没有对对象做初始化的操作,那么什么时候做的呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值