Spring BeanDefinitionRegistry 接口
Registry 登记/注册 顾名思义, 该接口设计的目的是用于保存和管理 Bean定义描述(BeanDefinition)
org.springframework.beans.factory.support.BeanDefinitionRegistry
package org.springframework.beans.factory.support;import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.AliasRegistry;/*** Interface for registries that hold bean definitions, for example RootBeanDefinition* and ChildBeanDefinition instances. Typically implemented by BeanFactories that* internally work with the AbstractBeanDefinition hierarchy.** Registry 登记/注册 顾名思义 该接口设计的目的是用于保存和管理 Bean定义描述(BeanDefinition), 例如: RootBeanDefinition 和 ChildBeanDefinition 实例** <p>This is the only interface in Spring's bean factory packages that encapsulates* <i>registration</i> of bean definitions. The standard BeanFactory interfaces* only cover access to a <i>fully configured factory instance</i>.** <p>Spring's bean definition readers expect to work on an implementation of this* interface. Known implementors within the Spring core are DefaultListableBeanFactory* and GenericApplicationContext.** @author Juergen Hoeller* @since 26.11.2003* @see org.springframework.beans.factory.config.BeanDefinition* @see AbstractBeanDefinition* @see RootBeanDefinition* @see ChildBeanDefinition* @see DefaultListableBeanFactory* @see org.springframework.context.support.GenericApplicationContext* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader* @see PropertiesBeanDefinitionReader*/
public interface BeanDefinitionRegistry extends AliasRegistry {/*** Register a new bean definition with this registry.* Must support RootBeanDefinition and ChildBeanDefinition.** 根据名称注册一个新的 BeanDefinition* @param beanName the name of the bean instance to register* @param beanDefinition definition of the bean instance to register* @throws BeanDefinitionStoreException if the BeanDefinition is invalid* @throws BeanDefinitionOverrideException if there is already a BeanDefinition* for the specified bean name and we are not allowed to override it* @see GenericBeanDefinition* @see RootBeanDefinition* @see ChildBeanDefinition*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;/*** Remove the BeanDefinition for the given name.** 根据名称移除一个 BeanDefinition* @param beanName the name of the bean instance to register* @throws NoSuchBeanDefinitionException if there is no such bean definition*/void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** Return the BeanDefinition for the given bean name.** 根据名称获取 BeanDefinition* @param beanName name of the bean to find a definition for* @return the BeanDefinition for the given name (never {@code null})* @throws NoSuchBeanDefinitionException if there is no such bean definition*/BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** Check if this registry contains a bean definition with the given name.* 检查给定名称是否已存在* @param beanName the name of the bean to look for* @return if this registry contains a bean definition with the given name*/boolean containsBeanDefinition(String beanName);/*** Return the names of all beans defined in this registry.* @return the names of all beans defined in this registry,* or an empty array if none defined*/String[] getBeanDefinitionNames();/*** Return the number of beans defined in the registry.* @return the number of beans defined in the registry*/int getBeanDefinitionCount();/*** Determine whether the bean definition for the given name is overridable,* i.e. whether {@link #registerBeanDefinition} would successfully return* against an existing definition of the same name.* <p>The default implementation returns {@code true}.** 判定给定的名称是否允许覆盖它的 BeanDefinition** @param beanName the name to check* @return whether the definition for the given bean name is overridable* @since 6.1*/default boolean isBeanDefinitionOverridable(String beanName) {return true;}/*** Determine whether the given bean name is already in use within this registry,* i.e. whether there is a local bean or alias registered under this name.* @param beanName the name to check* @return whether the given bean name is already in use*/boolean isBeanNameInUse(String beanName);
}
DefaultListableBeanFactory 的实现
大多数情况下, 我们项目的 BeanFactory 的实例是 DefaultListableBeanFactory, 它也是一个 BeanDefinitionRegistry
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {........./*** 注册一个 BeanDefinition 的方法*/@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (beanDefinition instanceof AbstractBeanDefinition abd) {try {abd.validate();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}// 获取一下是否有这个 bean 的 BeanDefinitionBeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {// 如果有 且 不允许覆盖, 则抛出 BeanDefinitionOverrideExceptionif (!isBeanDefinitionOverridable(beanName)) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}else if (existingDefinition.getRole() < beanDefinition.getRole()) {// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}}else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (isAlias(beanName)) {//判断下, 别名是否覆盖.String aliasedName = canonicalName(beanName);if (!isBeanDefinitionOverridable(aliasedName)) {if (containsBeanDefinition(aliasedName)) { // alias for existing bean definitionthrow new BeanDefinitionOverrideException(beanName, beanDefinition, getBeanDefinition(aliasedName));}else { // alias pointing to non-existing bean definitionthrow new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Cannot register bean definition for bean '" + beanName +"' since there is already an alias for bean '" + aliasedName + "' bound.");}}else {removeAlias(beanName);}}if (hasBeanCreationStarted()) {//bean 是否已经开始创建中. 后面再研究, 不是这个分支// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// 放到 beanDefinitionMap, key 是 beanName; value 是 beanDefinition;// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);// 别名 添加到 beanDefinitionNamesthis.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);}else if (isConfigurationFrozen()) {clearByTypeCache();}}/*** 移除一个 BeanDefinition 的方法*/@Overridepublic void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {Assert.hasText(beanName, "'beanName' must not be empty");//从 beanDefinitionMap 中移除BeanDefinition bd = this.beanDefinitionMap.remove(beanName);if (bd == null) {if (logger.isTraceEnabled()) {logger.trace("No bean named '" + beanName + "' found in " + this);}throw new NoSuchBeanDefinitionException(beanName);}//bean 是否已经开始创建中if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);updatedDefinitions.remove(beanName);this.beanDefinitionNames = updatedDefinitions;}}else {//从 beanDefinitionNames 中移除// Still in startup registration phasethis.beanDefinitionNames.remove(beanName);}this.frozenBeanDefinitionNames = null;resetBeanDefinition(beanName);}........
对于 DefaultListableBeanFactory 的实现主要就是使用两个集合存起来:
/*** 这个 Map 存储所有已注册 BeanDefinition, 其中 key是bean主要name, value 是 BeanDefinition*/private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);/** * 这个list 存储所有的 bean definition 名称 */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256);