ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BeanDefinition,beanDefinitionFactory,beanDefinitionRegestry的关系

2022-01-03 20:05:13  阅读:201  来源: 互联网

标签:beanDefinitionFactory String Nullable beanName 接口 bean beanDefinitionRegestry Be


      Spring 容器启动后首先是读取bean的xml配置文件,然后解析xml文件中的各种bean的定义,将xml文件中的每一个<bean />元素分别转换成一个BeanDefinition对象,其中保存了从配置文件中读取到的该bean的各种信息, 读完配置文件之后,得到了很多的BeanDefinition对象,然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中, 这就是Spring IOC容器启动时的基本流程. 

     下面我们们仔细研究一下 BeanDefinition,BeanDefinitionRegistry,BeanFactory 三个对象的组成及功能. 

1. BeanDefinition: 将Bean的定义信息存储到这个BeanDefinition相应的属性中,之后对Bean的操作就是直接对BeanDefinition进行的. 在这个接口中定义的属性有诸如类名、sccope、属性、构造函数参数列表、依赖的bean、是否单例类等. 
    它继承 AttributeAccessor 和 BeanMetadataElement 接口.  

  •       AttributeAccessor接口:   定义了对属性的修改,包括获取、设置、删除。
  •      BeanMetadataElement,Bean 元对象持有的配置元素可以通过 getSource() 方法来获取。

    BeanDefinition对应的就是<bean>元素的配置的属性信息,列表如下:


    
  1. bean标签的属性
  2. 1) scope: * *用来配置spring bean的作用域
  3. 2)singleton: * *表示bean为单例的
  4. 3)abstract:设置为 true,将该bean仅仅作为模板使用,应用程序上下文不会试图预先初始化它
  5. 4)lazy -init: * *设为 true,延迟加载,该bean不会在ApplicationContext启动时提前被实例化,而是第一次向容器通过getBean索取bean时实例化
  6. 注:只对singleton的bean起作用
  7. 5)autowire: * *自动装配
  8. 6)dependency - check:依赖检查
  9. 7)depends - on: * *表示一个bean的实例化依靠另一个bean先实例化
  10. 8)autowire -candidate: * *设为 false,容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其他bean自动装配的候选者,但是该bean本身可以使用自动装配来注入其他bean
  11. 9) primary:该bean优先被注入
  12. 10)init - method: * *初始化bean时调用的方法
  13. 11)destory - method: * *容器销毁之前所调用的方法
  14. 12)factory - method:当调用factory - method所指向的方法时,才开始实例化bean
  15. 13)factory -bean:调用静态工厂方法的方式创建bean
  16. 二、bean的子元素
  17. 1)meta:元数据,当需要使用里面的信息时可以通过key获取
  18. 2)lookup - method:获取器注入,是把一个方法声明为返回某种类型的bean但实际要返回的bean是在配置文件里面配置的
  19. 3)replaced - method:可以在运行时调用新的方法替换现有的方法,还能动态的更新原有方法的逻辑
  20. 4)constructor -arg: * * 对bean自动寻找对应的构造函数,并在初始化的时候将设置的参数传入进去
  21. 5)property: * * 基本数据类型赋值
  22. 6)qualifier: * * 通过Qualifier指定注入bean的名称

对以上信息进行包装的BeanDefinition的源代码如下:  ( 两张图可以对应着查看,是否一一对应)


    
  1. public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
  2. String SCOPE_SINGLETON = "singleton"; //单例模式
  3. String SCOPE_PROTOTYPE = "prototype"; //原型模式(就是正常情况下的)
  4. //此bean的角色
  5. int ROLE_APPLICATION = 0; //表示这个bean是用户定义的
  6. int ROLE_SUPPORT = 1; //表示这个bean是第三方插件或工具的
  7. int ROLE_INFRASTRUCTURE = 2; //表示这个bean是spring内部自己的
  8. //设置or获取此bean的父bean的名字
  9. void setParentName (@Nullable String var1);
  10. @Nullable
  11. String getParentName ();
  12. //设置or获取此bean的类名
  13. void setBeanClassName (@Nullable String var1);
  14. @Nullable
  15. String getBeanClassName ();
  16. //设置or获取此bean的模式(单例模式还是原型模式)
  17. void setScope (@Nullable String var1);
  18. @Nullable
  19. String getScope ();
  20. //设置or获取此bean的延迟初始化属性(true,false)
  21. void setLazyInit (boolean var1);
  22. boolean isLazyInit ();
  23. //设置or获取依赖
  24. void setDependsOn (@Nullable String... var1);
  25. @Nullable
  26. String[] getDependsOn();
  27. //设置or获取此bean的是否接受被自动装配(true, false)
  28. void setAutowireCandidate (boolean var1);
  29. boolean isAutowireCandidate ();
  30. //设置or获取是否是首要(true,false)
  31. void setPrimary (boolean var1);
  32. boolean isPrimary ();
  33. //设置or获取工厂bean的名字
  34. void setFactoryBeanName (@Nullable String var1);
  35. @Nullable
  36. String getFactoryBeanName ();
  37. //设置or 获取工厂bean里的生成方法名
  38. void setFactoryMethodName (@Nullable String var1);
  39. @Nullable
  40. String getFactoryMethodName ();
  41. //获取构造函数的所有参数值
  42. ConstructorArgumentValues getConstructorArgumentValues ();
  43. //判断构造函数参数是否为空
  44. default boolean hasConstructorArgumentValues () {
  45. return ! this.getConstructorArgumentValues().isEmpty();
  46. }
  47. //获取所有的property
  48. MutablePropertyValues getPropertyValues ();
  49. default boolean hasPropertyValues () {
  50. return ! this.getPropertyValues().isEmpty();
  51. }
  52. //设置or获取初始化方法名
  53. void setInitMethodName (@Nullable String var1);
  54. @Nullable
  55. String getInitMethodName ();
  56. //设置or获取销毁方法名
  57. void setDestroyMethodName (@Nullable String var1);
  58. @Nullable
  59. String getDestroyMethodName ();
  60. //设置角色,就是前面的三个整数(0,1,2),用户定义、第三方的、spring内部的
  61. void setRole (int var1);
  62. int getRole ();
  63. //设置or获取此bean的描述信息
  64. void setDescription (@Nullable String var1);
  65. @Nullable
  66. String getDescription ();
  67. //判断此bean是否是单例、原型、抽象的
  68. boolean isSingleton ();
  69. boolean isPrototype ();
  70. boolean isAbstract ();
  71. //获取资源描述,这个资源文件
  72. @Nullable
  73. String getResourceDescription ();
  74. @Nullable
  75. BeanDefinition getOriginatingBeanDefinition ();
  76. }

2. BeanDefinitionRegistry:    定义Bean的常规操作,来注册BeanDefinition, 内部就是用一个 Map 实现. 
   主要功能:

  • 以Map<String, BeanDefinition>的形式注册bean
  • 根据beanName 删除和获取 beanDefiniation
  • 得到持有的beanDefiniation的数目
  • 根据beanName 判断是否包含beanDefiniation

它的默认实现类,主要有三个:SimpleBeanDefinitionRegistry、DefaultListableBeanFactory、GenericApplicationContext

BeanDefinitionRegistry源码:


    
  1. public interface BeanDefinitionRegistry extends AliasRegistry {
  2. // 关键 -> 往注册表中注册一个新的 BeanDefinition 实例
  3. void registerBeanDefinition (String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
  4. // 移除注册表中已注册的 BeanDefinition 实例
  5. void removeBeanDefinition (String beanName) throws NoSuchBeanDefinitionException;
  6. // 从注册中心取得指定的 BeanDefinition 实例
  7. BeanDefinition getBeanDefinition (String beanName) throws NoSuchBeanDefinitionException;
  8. // 判断 BeanDefinition 实例是否在注册表中(是否注册)
  9. boolean containsBeanDefinition (String beanName);
  10. // 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
  11. String[] getBeanDefinitionNames();
  12. // 返回注册表中 BeanDefinition 实例的数量
  13. int getBeanDefinitionCount ();
  14. // beanName(标识)是否被占用
  15. boolean isBeanNameInUse (String beanName);
  16. }

它的三个实现类的区别

SimpleBeanDefinitionRegistry 是 BeanDefinitionRegistry 一个简单的实现,它还继承 SimpleAliasRegistry( AliasRegistry 的简单实现),它仅仅只提供注册表功能,无工厂功能。SimpleBeanDefinitionRegistry 使用 ConcurrentHashMap 来存储注册的 BeanDefinition。

DefaultListableBeanFactory,它是ConfigurableListableBeanFactory(其实就是 BeanFactory ) 和 BeanDefinitionRegistry 接口的默认实现:一个基于 BeanDefinition 元数据的完整 bean 工厂。它同样是用 ConcurrentHashMap 数据结构来存储注册的 BeanDefinition。

GenericApplicationContext ,他实现注册、注销功能都是委托 DefaultListableBeanFactory 实现的. 


    
  1. public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
  2. //底层是将操作委托给了 DefaultListableBeanFactory
  3. private final DefaultListableBeanFactory beanFactory;
  4. ......
  5. }

所以我们只看  DefaultListableBeanFactory的核心源码:


    
  1. // 注册表,由 BeanDefinition 的标识 (beanName) 与其实例组成
  2. private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, bean>( 64);
  3. // 标识(beanName)集合
  4. private final List<String> beanDefinitionNames = new ArrayList<String>( 64);
  5. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  6. throws BeanDefinitionStoreException {
  7. // 省略其他代码
  8. else {
  9. if (hasBeanCreationStarted()) {
  10. // Cannot modify startup-time collection elements anymore (for stable iteration)
  11. synchronized ( this.beanDefinitionMap) {
  12. this.beanDefinitionMap.put(beanName, beanDefinition);
  13. List<String> updatedDefinitions = new ArrayList<>( this.beanDefinitionNames.size() + 1);
  14. updatedDefinitions.addAll( this.beanDefinitionNames);
  15. updatedDefinitions.add(beanName);
  16. this.beanDefinitionNames = updatedDefinitions;
  17. if ( this.manualSingletonNames.contains(beanName)) {
  18. Set<String> updatedSingletons = new LinkedHashSet<>( this.manualSingletonNames);
  19. updatedSingletons.remove(beanName);
  20. this.manualSingletonNames = updatedSingletons;
  21. }
  22. }
  23. }
  24. else {
  25. // 注册 BeanDefinition ****最重要的一句
  26. this.beanDefinitionMap.put(beanName, beanDefinition);
  27. this.beanDefinitionNames.add(beanName);
  28. this.manualSingletonNames.remove(beanName);
  29. }
  30. this.frozenBeanDefinitionNames = null;
  31. }
  32. if (existingDefinition != null || containsSingleton(beanName)) {
  33. resetBeanDefinition(beanName);
  34. }
  35. }

3. BeanFactory :   创建Bean的工厂,  它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean,BeanFactory 的功能通过其他的接口得到不断扩展


    
  1. public interface BeanFactory {
  2. //这里是对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
  3. //如果需要得到工厂本身,需要转义
  4. String FACTORY_BEAN_PREFIX = "&";
  5. 这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。
  6. Object getBean (String name) throws BeansException;
  7. //这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根据名字取得的bean实例的Class类型和需要的不同的话。
  8. Object getBean (String name, Class requiredType) throws BeansException;
  9. //这里提供对bean的检索,看看是否在IOC容器有这个名字的bean
  10. boolean containsBean (String name);
  11. //这里根据bean名字得到bean实例,并同时判断这个bean是不是单件
  12. boolean isSingleton (String name) throws NoSuchBeanDefinitionException;
  13. //这里对得到bean实例的Class类型
  14. Class getType (String name) throws NoSuchBeanDefinitionException;
  15. //这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
  16. String[] getAliases(String name);
  17. }

BeanFactory下最通用的一个实现是 DefaultListableBeanFactory,它同时也实现了BeanDefinitionRegistry接口,因此它就承担了Bean的注册管理工作。

DefaultListableBeanFactory的类层次结构如下: 

DefaultListableBeanFactory其实要实现的功能就是以list集合的方式操作bean,为什么要拆成这么多的类和接口呢。这里面可能基于几点考虑。

  1. 功能的不同维度,分不同的接口,方便以后的维护和其他人的阅读。如:AutowireCapableBeanFactory、ListableBeanFactory、HierarchicalBeanFactory等
  2. 不同接口的实现,分布在不同的之类里,方便以后不同接口多种实现的扩展
  3. 从整个类图的分布,可以看出spring在这块是面向接口编程,后面类的实现,他们认为只是接口功能实现的一种,随时可以拓展成多种实现

通过名字就大概可以了解每个接口的功能: 

HierarchicalBeanFactory接口是在继承BeanFactory的基础上,实现BeanFactory的父子关系。
AutowireCapableBeanFactory接口是在继承BeanFactory的基础上,实现Bean的自动装配功能
ListableBeanFactory接口是在继承BeanFactory的基础上,实现Bean的list集合操作功能
ConfigurableBeanFactory接口是在继承HierarchicalBeanFactory的基础上,实现BeanFactory的全部配置管理功能, 
SingletonBeanRegistry是单例bean的注册接口
ConfigurableListableBeanFactory接口是继承AutowireCapableBeanFactory,ListableBeanFactory,ConfigurableBeanFactory三个接口的一个综合接口
AliasRegistry接口是别名注册接口,SimpleAliasRegistry类是简单的实现别名注册接口的类

标签:beanDefinitionFactory,String,Nullable,beanName,接口,bean,beanDefinitionRegestry,Be
来源: https://blog.csdn.net/Chen4852010/article/details/122291228

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有