SPRING05_BeanFactory概述HierarchicalBeanFactoryListableBeanFacotoryDefaultListableBeanFactory档案馆详解(代码片

Posted 所得皆惊喜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRING05_BeanFactory概述HierarchicalBeanFactoryListableBeanFacotoryDefaultListableBeanFactory档案馆详解(代码片相关的知识,希望对你有一定的参考价值。

①. 什么是BeanFactory(Bean工厂)?

  • ①. 按照上面的Spring的原理图,Spring的整个框架其实就是工厂里面造东西的流程,分析清楚工厂干了什么活,Spring的整个框架也就清楚了
  • ②. 进入BeanFactory里面就看到了核心的几句话:
    总结源码中的话语:利用原型模式返回Prototype类型的bean,而单例模式返回单例bean
/**
 * The root interface for accessing a Spring bean container.
 * 根接口,整个访问容器的入口
 * <p>This is the basic client view of a bean container;
 * further interfaces such as {@link ListableBeanFactory} and
 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
 * are available for specific purposes.
 * <p>This interface is implemented by objects that hold a number of bean definitions,
 * 这个接口是一个实现,保存很多的BeanDefinition信息,都有一个唯一的名字
 * each uniquely identified by a String name. Depending on the bean definition,
 * the factory will return either an independent instance of a contained object
 * (the Prototype design pattern), or a single shared instance (a superior
 * 这个工厂将会返回独立的实例或者返回一个共享的实例 (原型模式、单例模式)
 * alternative to the Singleton design pattern, in which the instance is a
 * singleton in the scope of the factory). 
 **/

②. BeanFactory类中分析

  • ①. BeanFactory(Bean的工厂),工厂无外乎就是简单工厂,抽象工厂,工厂方法

  • ②. 首先BeanFactory工厂里面暴露的方法有一个叫getBean(),这个是获取组件
    工厂最重要的就是造组件,然后返回的是一个T类型的对象,它只造bean

	<T> T getBean(Class<T> requiredType) throws BeansException;
  • ③. 它不是简单工厂模式,Spring在底层不是一个ifelse判断就能搞定的,它底层还很复杂,外部只提供了一个工厂方法,使用工厂方法模式,给我们造组件对象

  • ④. BeanFactory(Bean的工厂)里面下设三大工厂:俗称分厂

③. HierarchicalBeanFactory(继承树的工厂)

  • ①. 主要用于定义父子工厂(父子容器)
    getParentBeanFactory():获取它的父工厂
    containsLocalBean():判断工厂里面包不包含本地的一些bean

  • ②. 在spring的里面BeanFactory(Bean的工厂)下还有抽象工厂,但这些抽象工厂都没有创建产品的方法,相当于一个产品线,做一个产品,它的一个抽象工厂只是相当于对工厂的功能增强,跟产品没关系,所以它的这些抽象工厂不成立

  • ③. 抽象工厂想要成立就是:有总厂(BeanFactory) 总厂下的分厂要造产品的,对产品的接口会有其他规划

④. ListableBeanFacotory接口详解

  • ①. 主要保存了ioc容器中的核心信息
    getBeanDefinitionCount():获取bean定义信息的总和
    getBeanDefinitionNames():获取所有bean定义信息的名字
    getBeanNamesForType():还能按照类型获取bean名字

  • ②. 具体来查看下结构图
    下面的这个DefaultListableBeanFactory就是我们的档案库
    AbstractApplicationContext是环境类

  • ③. 详解AbstractApplicationContext如何是坏境类

  1. ResourceLoader资源读取器下的一个接口 == ResourcePatternResolver
  2. 抽象IOC容器(AbstractApplicationContext)拥有了资源加载器(ResourcePatternResolver)的接口
  3. 而且在对象一创建的时候,就拿到了,是用getResourcePatternResolver这个方法拿到的
  4. 这揭秘了一个策略模式的环境类就是AbstractApplicationContext
  5. 就是ioc容器拿到资源解析器,资源解析器只要传的不一样,IOC容器就可以从不一样的地方获取资源
  • ④. AnnotationConfigApplicationContext(ioc)容器->ConfigurableApplicationContext->ApplicationContext实现->ListableBeanFacotory
    我们用的IOC容器也是具有ListableBeanFacotory提供的功能,这个功能就是能列举出所有的bean
  • ⑤. 来到AbstractApplicationContext实现里面,还能看到一个bean的定义信息存在了哪个地方
  1. 我们用的是抽象的IOC容器(AbstractApplicationContext),抽象(AbstractApplicationContext)还有一个GenericApplicationContext
  2. 在GenericApplicationContext这个类里面包含了一个叫DefaultListableBeanFactory,
  3. 我们用的IOC容器的父类GenericApplicationContext,父类GenericApplicationContext里面有一个子属性,但这个子属性里面叫DefaultListableBeanFactory,这个DefaultListableBeanFactory是被组合进来的
  4. 现在又有一个组合关系就是:GenericApplicationContext组合了一个DefaultListableBeanFactory


  • ⑥. 组合DefaultListableBeanFactory有何用?
  1. DefaultListableBeanFactory它这里面有一些Map,serializableFactories这个map里面引入的是自己的工厂,组合模式,还是组合自己,自己组合自己会形成整个工厂的继承树,每一个工厂都会有它的一个唯一ID用Map,也就是说在Spring中整个用起来只有一个工厂,实际上Spring里面可以允许有无数个工厂,每一个工厂都能够造一些东西。
  2. 这样做的好处就是工厂跟工厂之间造的bean可以隔离起来,所以有的时候环境里面有某些bean不想让别人引用到,但是只需要它的这个范围内引用到就可以多个工厂模式,当然截止到目前,还没有看到任何一个项目里面有用到多工厂的,但是Spring底层有定义
  /** Map from serialized id to factory instance. */
  //这里引入的是自己的工厂,组合模式,还是组合自己,自己组合自己会形成整个工厂的继承树
  private static final Map<String, Reference<DefaultListableBeanFactory>> 
  serializableFactories =new ConcurrentHashMap<>(8);
/** List of bean definition names, in registration order. */
//beanDefinitionNames :bean定义的名字,这里就是保存bean定义的名字, 
//也就是资料库里面保存所有bean定义的名字
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

/** Map of singleton-only bean names, keyed by dependency type. */
//ingletonBeanNamesByType:按照类型保存单实例的,这也就解释了,spring底层,能够按照类型找到组
//件的一个底层池,其实就是在map拿,就是组件创建好了, 传一个类型,然后从这个map中得到这个类型对应
//的组件的名字,然后再从ioc容器中按照名字得到组件。
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

/** Map of singleton and non-singleton bean names, keyed by dependency type. */
//allBeanNamesByType:按照这个类型找到所有的bean
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

/** Map of bean definition objects, keyed by bean name. */
//beanDefinitionMap:所有bean定义信息的集合,按照名字以及对应BeanDefinition关系都保存好了,
//这也解释了Spring架构原理里面,Spring解析来的所有资源都会存在这个档案馆,这个档案馆就是一个
//beanDefinitionMap
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

⑤. DefaultListableBeanFactory档案馆

  • ①. 可以看出来DefaultListableBeanFactory是BeanDefinitionRegistry(Bean定义信息注册中心),也是SimpleAliasRegistry(别名中心),还是SingletonBeanRegistry(单实例bean的中心),还是BeanFactory(Bean工厂),所以这就是总档案馆(DefaultListableBeanFactory)

  • ②. 总档案馆DefaultListableBeanFactory虽然没有跟IOC容器形成父子关系,但它却形成了组合关系(IOC容器组合了整个总档案馆DefaultListableBeanFactory)

  • ③. DefaultListableBeanFactory在Spring中扮演者至关重要的角色

⑥. AutowireCapableBeanFactory

  • ①. 提供了自动装配能力,也就是BeanFactory还出了一个自动装配厂,这个自动装配厂只是扩展了一些功能

  • ②. 所有的自动装配功能由AutowireCapableBeanFactory定义,但最终的实现是有很多来实现这个方法

  • ③. AnnotationApplicationContext它自己没有自动装配能力,但是它组合了(DefaultListableBeanFactory)档案馆(它有自动装配能力),所以AnnotationApplicationContext也又有了自动装配能力。

以上是关于SPRING05_BeanFactory概述HierarchicalBeanFactoryListableBeanFacotoryDefaultListableBeanFactory档案馆详解(代码片的主要内容,如果未能解决你的问题,请参考以下文章

Spring源码--01--Spring概述

阶段3 2.Spring_03.Spring的 IOC 和 DI_5 BeanFactory和ApplicationContext的区别

[刘阳Java]_了解BeanFactory_第4讲

Spring IoC 容器详解 [Spring][IoC 控制反转][BeanFactory][ApplicationContext]

Spring IoC 容器详解 [Spring][IoC 控制反转][BeanFactory][ApplicationContext]

Spring_11-Spring5总结