DefaultListableBeanFactory

image.png

1.BeanFactory的三个亲子接口

image.png
上图展示的是BeanFactory的三个儿子,这三个接口分别对BeanFactory进行了功能上的扩展

  1. ListableBeanFactory:对Bean信息、Bean定义信息进行查询操作
    1. 涉及一个工具类:_BeanFactoryUtils_
  2. HierarchicalBeanFactory:增加BeanFactory的父子关系的支持
  3. AutowireCapableBeanFactory:提供创建Bean、应用后置处理器、自动注入等方法定义

    2.SingletonBeanRegistry

    此类需要被BeanFactory的类实现,其作用是为单例Bean的获取注册提供统一的操作行为

    3.AliasRegistry

    提供别名的增删改操作

    3.1BeanDefinitionRegistry

    继承AliasRegistry,定义了一系列关于BeanDefinition的CRUD

    3.1SimpleAliasRegistry (实现类)

    这是一个实现类,纯纯的就是对AliasRegistry定义的行为进行实现 ```java public class SimpleAliasRegistry implements AliasRegistry {

    /* Logger available to subclasses. / protected final Log logger = LogFactory.getLog(getClass());

    /* 存放的是别名->规范的名 / private final Map aliasMap = new ConcurrentHashMap<>(16);

  1. @Override
  2. public void registerAlias(String name, String alias) {
  3. Assert.hasText(name, "'name' must not be empty");
  4. Assert.hasText(alias, "'alias' must not be empty");
  5. synchronized (this.aliasMap) {
  6. if (alias.equals(name)) {
  7. //name和alias相同时直接remove
  8. this.aliasMap.remove(alias);
  9. }
  10. else {
  11. String registeredName = this.aliasMap.get(alias);
  12. if (registeredName != null) {
  13. //若已经有相关的 alias啦
  14. if (registeredName.equals(name)) {
  15. // An existing alias - no need to re-register
  16. return;
  17. }
  18. if (!allowAliasOverriding()) {
  19. //不允许重复Alias
  20. throw new IllegalStateException();
  21. }
  22. //日志
  23. }
  24. //别名循环 A->B->A
  25. checkForAliasCircle(name, alias);
  26. this.aliasMap.put(alias, name);
  27. //日志
  28. }
  29. }
  30. }
  31. /**
  32. * Determine whether alias overriding is allowed.
  33. * <p>Default is {@code true}.
  34. */
  35. protected boolean allowAliasOverriding() {
  36. return true;
  37. }
  38. /**
  39. * Determine whether the given name has the given alias registered.
  40. * @param name the name to check
  41. * @param alias the alias to look for
  42. * @since 4.2.1
  43. */
  44. public boolean hasAlias(String name, String alias) {
  45. String registeredName = this.aliasMap.get(alias);
  46. return ObjectUtils.nullSafeEquals(registeredName, name) || (registeredName != null
  47. && hasAlias(name, registeredName));
  48. }
  49. @Override
  50. public void removeAlias(String alias) {
  51. synchronized (this.aliasMap) {
  52. String name = this.aliasMap.remove(alias);
  53. //日志
  54. }
  55. }
  56. @Override
  57. public boolean isAlias(String name) {
  58. return this.aliasMap.containsKey(name);
  59. }
  60. @Override
  61. public String[] getAliases(String name) {
  62. List<String> result = new ArrayList<>();
  63. synchronized (this.aliasMap) {
  64. retrieveAliases(name, result);
  65. }
  66. return StringUtils.toStringArray(result);
  67. }
  68. /**
  69. * Transitively retrieve all aliases for the given name.
  70. * @param name the target name to find aliases for
  71. * @param result the resulting aliases list
  72. */
  73. private void retrieveAliases(String name, List<String> result) {
  74. this.aliasMap.forEach((alias, registeredName) -> {
  75. if (registeredName.equals(name)) {
  76. result.add(alias);
  77. retrieveAliases(alias, result);
  78. }
  79. });
  80. }
  81. /**
  82. * Resolve all alias target names and aliases registered in this
  83. * registry, applying the given {@link StringValueResolver} to them.
  84. * <p>The value resolver may for example resolve placeholders
  85. * in target bean names and even in alias names.
  86. * @param valueResolver the StringValueResolver to apply
  87. */
  88. public void resolveAliases(StringValueResolver valueResolver) {
  89. Assert.notNull(valueResolver, "StringValueResolver must not be null");
  90. synchronized (this.aliasMap) {
  91. Map<String, String> aliasCopy = new HashMap<>(this.aliasMap);
  92. aliasCopy.forEach((alias, registeredName) -> {
  93. String resolvedAlias = valueResolver.resolveStringValue(alias);
  94. String resolvedName = valueResolver.resolveStringValue(registeredName);
  95. if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) {
  96. this.aliasMap.remove(alias);
  97. }
  98. else if (!resolvedAlias.equals(alias)) {
  99. String existingName = this.aliasMap.get(resolvedAlias);
  100. if (existingName != null) {
  101. if (existingName.equals(resolvedName)) {
  102. // Pointing to existing alias - just remove placeholder
  103. this.aliasMap.remove(alias);
  104. return;
  105. }
  106. throw new IllegalStateException(
  107. "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias +
  108. "') for name '" + resolvedName + "': It is already registered for name '" +
  109. registeredName + "'.");
  110. }
  111. checkForAliasCircle(resolvedName, resolvedAlias);
  112. this.aliasMap.remove(alias);
  113. this.aliasMap.put(resolvedAlias, resolvedName);
  114. }
  115. else if (!registeredName.equals(resolvedName)) {
  116. this.aliasMap.put(alias, resolvedName);
  117. }
  118. });
  119. }
  120. }
  121. /**
  122. * Check whether the given name points back to the given alias as an alias
  123. * in the other direction already, catching a circular reference upfront
  124. * and throwing a corresponding IllegalStateException.
  125. * @param name the candidate name
  126. * @param alias the candidate alias
  127. * @see #registerAlias
  128. * @see #hasAlias
  129. */
  130. protected void checkForAliasCircle(String name, String alias) {
  131. if (hasAlias(alias, name)) {
  132. throw new IllegalStateException(");
  133. }
  134. }
  135. /**
  136. * Determine the raw name, resolving aliases to canonical names.
  137. * @param name the user-specified name
  138. * @return the transformed name
  139. */
  140. public String canonicalName(String name) {
  141. String canonicalName = name;
  142. // Handle aliasing...
  143. String resolvedName;
  144. do {
  145. resolvedName = this.aliasMap.get(canonicalName);
  146. if (resolvedName != null) {
  147. canonicalName = resolvedName;
  148. }
  149. }
  150. while (resolvedName != null);
  151. return canonicalName;
  152. }

}

  1. <a name="Fr2Mc"></a>
  2. ## 4.DefaultSingletonBeanRegistry(实现类)
  3. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1609516/1655253809785-d6e9ec63-e45f-42c6-9236-c3ba203bebf5.png#clientId=u81e1cd3f-1762-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=321&id=u4c6ef407&margin=%5Bobject%20Object%5D&name=image.png&originHeight=214&originWidth=495&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9245&status=done&style=none&taskId=ubf52d602-c776-437a-8687-282509bb146&title=&width=743)<br />作用:是对`SingletonBeanRegistry`的实现,对单例Bean进行管理
  4. ```java
  5. /** Cache of singleton objects: bean name --> bean instance 缓存单例对象 */
  6. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  7. /** Cache of singleton factories: bean name --> ObjectFactory 缓存单例对象工厂 */
  8. private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  9. /** Cache of early singleton objects: bean name --> bean instance 缓存早期Bean */
  10. private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
  11. /** BeanNames集合(顺序按照注册顺序)*/
  12. private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
  13. /** 正在创建的BeanName */
  14. private final Set<String> singletonsCurrentlyInCreation =
  15. Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  16. /** Names of beans currently excluded from in creation checks */
  17. private final Set<String> inCreationCheckExclusions =
  18. Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  19. /** List of suppressed Exceptions, available for associating related causes */
  20. @Nullable
  21. private Set<Exception> suppressedExceptions;
  22. /** Flag that indicates whether we're currently within destroySingletons */
  23. private boolean singletonsCurrentlyInDestruction = false;
  24. /** Disposable 类型的 bean instances: bean name --> disposable instance */
  25. private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
  26. /** Map between containing bean names: bean name --> 依赖的beanName集合 Set of bean names that the bean contains */
  27. private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
  28. /** Map between dependent bean names: bean name --> Set of dependent bean names */
  29. private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
  30. /** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
  31. private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

4.1FactoryBeanRegistrySupport(抽象类)

image.png

  1. FactoryBean直接基础DefaultSingletonBeanRegistry,增加了对FactoryBean的特殊处理功能

    5.ConfigurableBeanFactory

    image.png
    提供了配置bean的方法

    5.1ConfigurableListableBeanFactory

    ConfigurableBeanFactory的基础上把ListableBeanFactoryAutowireCapableBeanFactory进行了继承,新增了忽略类型及接口的方法定义
    image.png

    6.AbstractBeanFactory(抽象类)

    抽象类,实现了ConfigurableBeanFactory和继承FactoryBeanRegistrySupport对子类公共的功能进行了实现
    image.png

    6.1AbstractAutowireCapableBeanFactory(抽象类)

    抽象类,继承AbstractBeanFactory同时实现了AutowireCapableBeanFactory
    image.png

    小结

    DefaultListableBeanFactory实现了ConfigurableListableBeanFactory(这个接口拥有三个主要接口功能)和BeanDefinition接口并继承了AbstractAutowireCapableBeanFactory

    XmlBeanFactory是对DefaultListableBeanFactory的扩展,添加了能够从XML文件中读取BeanDefinition的功能,其实现类是XmlBeanDefinitionReader

  1. @Deprecated
  2. @SuppressWarnings({"serial", "all"})
  3. public class XmlBeanFactory extends DefaultListableBeanFactory {
  4. private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
  5. //....................
  6. }

XmlBeanDefinitionReader

image.png
image.png

BeanDefinitionReader

定义BeanDefinition读取的动作

EnvironmentCapable

获取Environment

ResourceLoader

类资源加载器,在AbstractBeanDefinitionReader中引用

DocumentLoader

定义文件转换为Document的功能,如将XML文件转换为Document对象

BeanDefinitionDocumentReader

读取Document对象中BenaDefinition,是在方法中创建获取的

DefaultBeanDefinitionDocumentReader

实现了BeanDefinitionDocumentReader

BeanDefinitionParserDelegate

定义解析各种Element的各种方法

步骤描述

  1. 通过ResourceLoader将资源文件读取成为Resource
  2. 通过DocumentLoaderResource转换为Document对象
  3. 通过DefaultBeanDefinitionDocumentReaderDocument对象进行解析,并使用BeanDefinitionParserDelegateElement进行解析