BeanFactory功能与设计原理

 1.BeanFactory功能

image.pngimage.png

  • 具体的方法的功能通过方法名可知,其中,isTypeMatch()是用来查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
  • 另外需要注意的是有个常量FACTORY_BEAN_PREFIX = "&";这个主要是用于FactoryBean上。FactoryBean和BeanFactory的区别需要知道:BeanFactory是一个工厂,也就是一个容器,是来管理bean的;FactoryBean是一个bean,所以也是由BeanFactory来管理的,不过FactoryBean不是一个普通的Bean,它会表现出工厂模式的样子(也可以理解为修饰器),是一个能产生或者修饰对象生成的工厂Bean,里面的getObject()就是用来获取FactoryBean产生的对象。所以在BeanFactory中使用“&”来得到FactoryBean本身,用来区分通过容器获取FactoryBean产生的对象还是获取FactoryBean本身。



 2.BeanFactory的设计原理

image.png

image.png

  • BeanFactory接口提供了使用IoC容器的规范。在这个基础上,Spring还提供了符合这个IoC容器接口的一系列容器的实现供开发人员使用。这里以XmlBeanFactory的实现为例来说明简单IoC容器的设计原理。
  • 在继承体系中,XmlBeanFactory继承自DefaultListableBeanFactory这个类,后者非常重要,是经常要用到的一个IoC容器的实现,比如在设计应用上下文ApplicationContext时就会用到它。DefaultListableBeanFactory实际上包含了基本IoC容器所具有的重要功能,通过查看源码可知许多我们正常使用的基本容器(如XmlBeanFactory)和ApplicationContext都是以这个容器为基础的。
  • 在Spring中,实际上是把DefaultListableBeanFactory作为一个默认的功能完整的IoC容器来使用的。XmlBeanFactory在继承了DefaultListableBeanFactory容器的功能的同时,增加了新的功能,这些功能很容易从XmlBeanFactory的名字上猜到。它是一个与XML相关的BeanFactory,也就是说它是一个可以读取以XML文件方式定义的BeanDefinition的IoC容器。构造XmlBeanFactory这个loC容器时,需要指定BeanDefinition的信息来源,而这个信息来源需要封装成Spring中的Resource类来给出。Resource是Spring用来封装I/O操作的类。比如,我们的BeanDefinition信息是以XML文件形式存在的,那么可以使用像ClassPathResourcere s=new ClassPathResource("beans.xml");这样具体的ClassPathResource来构造需要的Resource,然后将Resource作为构造参数传递给XmlBeanFactory构造函数。这样,IoC容器就可以方便地定位到需要的BeanDefinition信息来对Bean完成容器的初始化和依赖注入过程。
  • 参考了XmlBeanFactory的实现,我们可以了解到使用基本容器(这里指的是DefaultListableBeanFactory)的基本过程。需要几个关键的组件(Resource、BeanDefinitionReader和DefaultListableBeanFactory,其实也就是这三个组件来对应IoC初始化的三个过程:定位,载入和注册。定位就是找到相应的配置文件,转换为抽象资源(Resource),载入就是BeanDefinitionReader.loadBeanDefinitions(resource)所做的事,将抽象资源解析为BeanDefinition,BeanDefinition是Spring用来表示我们所定义的Bean的数据结构。注册就是将BeanDefinition“存储”在BeanFactory中。下面是编程式使用IoC容器:

ClassPathResource res = new ClassPathResource("beans .xml");//定位
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);//开始载入的入口函数,载入完就注册


原文地址:https://www.cnblogs.com/huangzefeng/p/10322383.html