找回密码
 立即注册
首页 业界区 安全 Spring BeanDefinitionRegistry 接口

Spring BeanDefinitionRegistry 接口

剽达崖 7 天前
Spring BeanDefinitionRegistry 接口

Registry 登记/注册 顾名思义, 该接口设计的目的是用于保存和管理 Bean定义描述(BeanDefinition)
org.springframework.beans.factory.support.BeanDefinitionRegistry
  1. package org.springframework.beans.factory.support;
  2. import org.springframework.beans.factory.BeanDefinitionStoreException;
  3. import org.springframework.beans.factory.NoSuchBeanDefinitionException;
  4. import org.springframework.beans.factory.config.BeanDefinition;
  5. import org.springframework.core.AliasRegistry;
  6. /**
  7. * Interface for registries that hold bean definitions, for example RootBeanDefinition
  8. * and ChildBeanDefinition instances. Typically implemented by BeanFactories that
  9. * internally work with the AbstractBeanDefinition hierarchy.
  10. *
  11. * Registry 登记/注册 顾名思义 该接口设计的目的是用于保存和管理 Bean定义描述(BeanDefinition), 例如:  RootBeanDefinition 和 ChildBeanDefinition 实例
  12. *
  13. * <p>This is the only interface in Spring's bean factory packages that encapsulates
  14. * <i>registration</i> of bean definitions. The standard BeanFactory interfaces
  15. * only cover access to a <i>fully configured factory instance</i>.
  16. *
  17. * <p>Spring's bean definition readers expect to work on an implementation of this
  18. * interface. Known implementors within the Spring core are DefaultListableBeanFactory
  19. * and GenericApplicationContext.
  20. *
  21. * @author Juergen Hoeller
  22. * @since 26.11.2003
  23. * @see org.springframework.beans.factory.config.BeanDefinition
  24. * @see AbstractBeanDefinition
  25. * @see RootBeanDefinition
  26. * @see ChildBeanDefinition
  27. * @see DefaultListableBeanFactory
  28. * @see org.springframework.context.support.GenericApplicationContext
  29. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
  30. * @see PropertiesBeanDefinitionReader
  31. */
  32. public interface BeanDefinitionRegistry extends AliasRegistry {
  33.         /**
  34.          * Register a new bean definition with this registry.
  35.          * Must support RootBeanDefinition and ChildBeanDefinition.
  36.          *
  37.          * 根据名称注册一个新的 BeanDefinition
  38.          * @param beanName the name of the bean instance to register
  39.          * @param beanDefinition definition of the bean instance to register
  40.          * @throws BeanDefinitionStoreException if the BeanDefinition is invalid
  41.          * @throws BeanDefinitionOverrideException if there is already a BeanDefinition
  42.          * for the specified bean name and we are not allowed to override it
  43.          * @see GenericBeanDefinition
  44.          * @see RootBeanDefinition
  45.          * @see ChildBeanDefinition
  46.          */
  47.         void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  48.                         throws BeanDefinitionStoreException;
  49.         /**
  50.          * Remove the BeanDefinition for the given name.
  51.          *
  52.          * 根据名称移除一个 BeanDefinition
  53.          * @param beanName the name of the bean instance to register
  54.          * @throws NoSuchBeanDefinitionException if there is no such bean definition
  55.          */
  56.         void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
  57.         /**
  58.          * Return the BeanDefinition for the given bean name.
  59.          *
  60.          * 根据名称获取 BeanDefinition
  61.          * @param beanName name of the bean to find a definition for
  62.          * @return the BeanDefinition for the given name (never {@code null})
  63.          * @throws NoSuchBeanDefinitionException if there is no such bean definition
  64.          */
  65.         BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
  66.         /**
  67.          * Check if this registry contains a bean definition with the given name.
  68.          * 检查给定名称是否已存在
  69.          * @param beanName the name of the bean to look for
  70.          * @return if this registry contains a bean definition with the given name
  71.          */
  72.         boolean containsBeanDefinition(String beanName);
  73.         /**
  74.          * Return the names of all beans defined in this registry.
  75.          * @return the names of all beans defined in this registry,
  76.          * or an empty array if none defined
  77.          */
  78.         String[] getBeanDefinitionNames();
  79.         /**
  80.          * Return the number of beans defined in the registry.
  81.          * @return the number of beans defined in the registry
  82.          */
  83.         int getBeanDefinitionCount();
  84.         /**
  85.          * Determine whether the bean definition for the given name is overridable,
  86.          * i.e. whether {@link #registerBeanDefinition} would successfully return
  87.          * against an existing definition of the same name.
  88.          * <p>The default implementation returns {@code true}.
  89.          *
  90.          *  判定给定的名称是否允许覆盖它的 BeanDefinition
  91.          *
  92.          * @param beanName the name to check
  93.          * @return whether the definition for the given bean name is overridable
  94.          * @since 6.1
  95.          */
  96.         default boolean isBeanDefinitionOverridable(String beanName) {
  97.                 return true;
  98.         }
  99.         /**
  100.          * Determine whether the given bean name is already in use within this registry,
  101.          * i.e. whether there is a local bean or alias registered under this name.
  102.          * @param beanName the name to check
  103.          * @return whether the given bean name is already in use
  104.          */
  105.         boolean isBeanNameInUse(String beanName);
  106. }
复制代码
DefaultListableBeanFactory 的实现

大多数情况下, 我们项目的 BeanFactory 的实例是 DefaultListableBeanFactory, 它也是一个 BeanDefinitionRegistry
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
  1. public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory  
  2.        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
  3.       
  4.       
  5.        .........
  6.        
  7.         /**
  8.          * 注册一个 BeanDefinition 的方法
  9.          */
  10.         @Override
  11.         public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  12.                         throws BeanDefinitionStoreException {
  13.                 Assert.hasText(beanName, "Bean name must not be empty");
  14.                 Assert.notNull(beanDefinition, "BeanDefinition must not be null");
  15.                 if (beanDefinition instanceof AbstractBeanDefinition abd) {
  16.                         try {
  17.                                 abd.validate();
  18.                         }
  19.                         catch (BeanDefinitionValidationException ex) {
  20.                                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
  21.                                                 "Validation of bean definition failed", ex);
  22.                         }
  23.                 }
  24.                 // 获取一下是否有这个 bean 的 BeanDefinition
  25.                 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
  26.                 if (existingDefinition != null) {
  27.                         // 如果有 且 不允许覆盖, 则抛出 BeanDefinitionOverrideException
  28.                         if (!isBeanDefinitionOverridable(beanName)) {
  29.                                 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
  30.                         }
  31.                         else if (existingDefinition.getRole() < beanDefinition.getRole()) {
  32.                                 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
  33.                                 if (logger.isInfoEnabled()) {
  34.                                         logger.info("Overriding user-defined bean definition for bean '" + beanName +
  35.                                                         "' with a framework-generated bean definition: replacing [" +
  36.                                                         existingDefinition + "] with [" + beanDefinition + "]");
  37.                                 }
  38.                         }
  39.                         else if (!beanDefinition.equals(existingDefinition)) {
  40.                                 if (logger.isDebugEnabled()) {
  41.                                         logger.debug("Overriding bean definition for bean '" + beanName +
  42.                                                         "' with a different definition: replacing [" + existingDefinition +
  43.                                                         "] with [" + beanDefinition + "]");
  44.                                 }
  45.                         }
  46.                         else {
  47.                                 if (logger.isTraceEnabled()) {
  48.                                         logger.trace("Overriding bean definition for bean '" + beanName +
  49.                                                         "' with an equivalent definition: replacing [" + existingDefinition +
  50.                                                         "] with [" + beanDefinition + "]");
  51.                                 }
  52.                         }
  53.                         this.beanDefinitionMap.put(beanName, beanDefinition);
  54.                 }
  55.                 else {
  56.                         if (isAlias(beanName)) {
  57.                                 //判断下, 别名是否覆盖.
  58.                                 String aliasedName = canonicalName(beanName);
  59.                                 if (!isBeanDefinitionOverridable(aliasedName)) {
  60.                                         if (containsBeanDefinition(aliasedName)) {  // alias for existing bean definition
  61.                                                 throw new BeanDefinitionOverrideException(
  62.                                                                 beanName, beanDefinition, getBeanDefinition(aliasedName));
  63.                                         }
  64.                                         else {  // alias pointing to non-existing bean definition
  65.                                                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
  66.                                                                 "Cannot register bean definition for bean '" + beanName +
  67.                                                                 "' since there is already an alias for bean '" + aliasedName + "' bound.");
  68.                                         }
  69.                                 }
  70.                                 else {
  71.                                         removeAlias(beanName);
  72.                                 }
  73.                         }
  74.                         if (hasBeanCreationStarted()) {
  75.                                 //bean 是否已经开始创建中. 后面再研究, 不是这个分支
  76.                                 // Cannot modify startup-time collection elements anymore (for stable iteration)
  77.                                 synchronized (this.beanDefinitionMap) {
  78.                                         this.beanDefinitionMap.put(beanName, beanDefinition);
  79.                                         List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
  80.                                         updatedDefinitions.addAll(this.beanDefinitionNames);
  81.                                         updatedDefinitions.add(beanName);
  82.                                         this.beanDefinitionNames = updatedDefinitions;
  83.                                         removeManualSingletonName(beanName);
  84.                                 }
  85.                         }
  86.                         else {
  87.                                 // 放到 beanDefinitionMap, key 是 beanName; value 是 beanDefinition;
  88.                                 // Still in startup registration phase
  89.                                 this.beanDefinitionMap.put(beanName, beanDefinition);
  90.                                 // 别名 添加到 beanDefinitionNames
  91.                                 this.beanDefinitionNames.add(beanName);
  92.                                 removeManualSingletonName(beanName);
  93.                         }
  94.                         this.frozenBeanDefinitionNames = null;
  95.                 }
  96.                 if (existingDefinition != null || containsSingleton(beanName)) {
  97.                         resetBeanDefinition(beanName);
  98.                 }
  99.                 else if (isConfigurationFrozen()) {
  100.                         clearByTypeCache();
  101.                 }
  102.         }
  103.         /**
  104.          * 移除一个 BeanDefinition 的方法
  105.          */
  106.         @Override
  107.         public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
  108.                 Assert.hasText(beanName, "'beanName' must not be empty");
  109.                 //从 beanDefinitionMap 中移除
  110.                 BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
  111.                 if (bd == null) {
  112.                         if (logger.isTraceEnabled()) {
  113.                                 logger.trace("No bean named '" + beanName + "' found in " + this);
  114.                         }
  115.                         throw new NoSuchBeanDefinitionException(beanName);
  116.                 }
  117.                 //bean 是否已经开始创建中
  118.                 if (hasBeanCreationStarted()) {
  119.                         // Cannot modify startup-time collection elements anymore (for stable iteration)
  120.                         synchronized (this.beanDefinitionMap) {
  121.                                 List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);
  122.                                 updatedDefinitions.remove(beanName);
  123.                                 this.beanDefinitionNames = updatedDefinitions;
  124.                         }
  125.                 }
  126.                 else {
  127.                         //从 beanDefinitionNames 中移除
  128.                         // Still in startup registration phase
  129.                         this.beanDefinitionNames.remove(beanName);
  130.                 }
  131.                 this.frozenBeanDefinitionNames = null;
  132.                 resetBeanDefinition(beanName);
  133.         }
  134.     ........
复制代码
对于 DefaultListableBeanFactory 的实现主要就是使用两个集合存起来:
  1.         /**
  2.          * 这个 Map 存储所有已注册 BeanDefinition, 其中 key是bean主要name, value 是 BeanDefinition
  3.          */
  4.         private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  5.         /**  
  6.          * 这个list 存储所有的 bean definition 名称  
  7.          */  
  8.         private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
  9.        
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册