3.1、Spring源码学习:认识 DefaultListableBeanFactory

r囧r小猫 2024-04-17 21:21 185阅读 0赞

文章目录

      • 前言
      • DefaultListableBeanFactory
        • DefaultListableBeanFactory 中的一些常量
      • AbstractAutowireCapableBeanFactory
        • AbstractAutowireCapableBeanFactory 全局变量介绍
        • Spring 关于循环依赖的两个常量

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好。

DefaultListableBeanFactory

org.springframework.beans.factory.support.DefaultListableBeanFactory
DefaultListableBeanFactory 是一个非常重要的 BeanFactory,是Spring 中的一个核心类。
DefaultListableBeanFactory 是Spring中默认的ListableBeanFactory和BeanDefinitionRegistry的实现类,已经包含了比较全面的功能,可以作为单例工厂直接使用,也可以将其作为父类进行扩展。
典型的应用方法是,在调用相关的SpringBean之前,通过Bean定义文件对Bean进行注册。你不用担心这个前置操作会消耗太多性能,因为通过操作本地的一个包含了Bean定义信息的不可变对象来注册Bean还是很快的。

在这里插入图片描述

DefaultListableBeanFactory 中的一些常量

其中有几个变量我们单独说下:
默认情况后,允许重复加载同名bean,后面的覆盖前面的。
默认情况下,允许立即加载遇到的bean,即使配置了懒加载。

  1. private static Class<?> javaUtilOptionalClass = null;
  2. private static Class<?> javaxInjectProviderClass = null;
  3. static {
  4. try {
  5. javaUtilOptionalClass =
  6. ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader());
  7. }
  8. catch (ClassNotFoundException ex) {
  9. // Java 8 not available - Optional references simply not supported then.
  10. }
  11. try {
  12. javaxInjectProviderClass =
  13. ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
  14. }
  15. catch (ClassNotFoundException ex) {
  16. // JSR-330 API not available - Provider interface simply not supported then.
  17. }
  18. }
  19. /** Map:key:序列化ID,value:DefaultListableBeanFactory实例对象*/
  20. private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
  21. new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
  22. /** 该 工厂 的可选id,用于序列化 */
  23. private String serializationId;
  24. /** 是否允许同名 bean 定义的从新注册,即同名bean定义,后面的注册能否覆盖之前的,默认是可以 */
  25. private boolean allowBeanDefinitionOverriding = true;
  26. /** 是否允许 eager class loading(立即加载) 包括对于 lazy-init beans,默认是允许 */
  27. private boolean allowEagerClassLoading = true;
  28. /** 可选的用于依赖集合和数组的顺序比较器 */
  29. private Comparator<Object> dependencyComparator;
  30. /**用于检测 Bean 是否有 自动注入请求 */
  31. private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
  32. /** 保存 依赖类型 和 依赖的对象 的map */
  33. private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);
  34. /** 保存“bean的定义”的对象的Map,key:bean的名字, value:定义bean的相关对象 */
  35. private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
  36. /**map ,保存key:依赖类型,value:单例和非单例 bean的名字*/
  37. private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
  38. /** map,key:依赖类型,value:单例bean的名字*/
  39. private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
  40. /** list:bean定义的名字,按照注册顺序保存 */
  41. private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
  42. /** list:手工注册单例bean的名字,按照注册顺序 */
  43. private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
  44. /** 为了冻结配置 提供的 bean名字的缓存数组 */
  45. private volatile String[] frozenBeanDefinitionNames;
  46. /** 是否允许bean定义的元数据被缓存,以用于所有的bean,默认是否 */
  47. private volatile boolean configurationFrozen = false;

AbstractAutowireCapableBeanFactory

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 是 DefaultListableBeanFactory 的父类。

有几个比较重要的变量:
默认允许循环依赖。
默认的实例化策略为 cglib动态代理,即cglib为代理类生成子类的方式对方法进行注入。
默认情况下,如果循环依赖失败,不允许注入原始的bean——比如这个bean经过AOP包装。
有些类比如String不会被检测和注入依赖。
有些接口也不会被检测和注入依赖, 默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略
未完成实例化的bean会被先保存在 factoryBeanInstanceCache 这个缓存map中。

AbstractAutowireCapableBeanFactory 全局变量介绍

这里我们看下 AbstractAutowireCapableBeanFactory 中的全局变量

  1. /** 创建 bean实例的策略 默认使用 Cglib 动态代理,即以动态生成子类的方式对方法进行注入*/
  2. private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
  3. /** 方法参数名称的解析策略 */
  4. private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
  5. /** 是否允许循环依赖的 beans,默认是允许的 */
  6. private boolean allowCircularReferences = true;
  7. /** * 是否在循环依赖的时候尝试将 bean 的原始对象注入到参数中,即使这个bean是被包装的(比如AOP),默认是否 */
  8. private boolean allowRawInjectionDespiteWrapping = false;
  9. /** * 设置需要忽略依赖检测和注入的类型,比如 String */
  10. private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();
  11. /** * 设置需要忽略依赖和注入的接口,默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略 */
  12. private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
  13. /** 没有完成实例化的 FactoryBean 缓存map,key:FactoryBean 名称 ,value:BeanWrapper */
  14. private final Map<String, BeanWrapper> factoryBeanInstanceCache =
  15. new ConcurrentHashMap<String, BeanWrapper>(16);
  16. /** 过滤了的属性描述器 缓存map, key:bean Class,value:PropertyDescriptor 数据,最多256个 */
  17. private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
  18. new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(256);

Spring 关于循环依赖的两个常量

AbstractAutowireCapableBeanFactory 中关于 循环依赖的变量 allowCircularReferences 和 allowRawInjectionDespiteWrapping 。
实时上,Spring 仅允许单例模式下的允许依赖,并且在循环依赖无法完成注入时,默认不采取原始类型对象的注入。

  1. /** 是否允许循环依赖的 beans,默认是允许的 */
  2. private boolean allowCircularReferences = true;
  3. /** * 是否在循环依赖的时候尝试将 bean 的原始对象注入到参数中,即使这个bean是被包装的(比如AOP),默认是否 */
  4. private boolean allowRawInjectionDespiteWrapping = false;

发表评论

表情:
评论列表 (有 0 条评论,185人围观)

还没有评论,来说两句吧...

相关阅读