首页 > 其他分享 >Spring5 IOC容器解析——BeanDefinition的注册

Spring5 IOC容器解析——BeanDefinition的注册

时间:2023-01-07 17:31:59浏览次数:65  
标签:name beanName alias bean String Spring5 IOC BeanDefinition

前言

在上一篇文章解析BeanDefinition 对配置文件解析完成后,获取的beanDefiniton已经可以进行使用了,剩下的唯一工作就是注册了,也就是processBeanDefinition方法中的BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())代码的解析了。

BeanDefinitionRegistry

该类的作用主要是向注册表中注册 BeanDefinition 实例,完成 注册的过程。 它的接口定义如下:

public interface BeanDefinitionRegistry extends AliasRegistry {

	/**
	 * 往注册表中注册一个新的 BeanDefinition 实例
	 * Register a new bean definition with this registry.
	 * Must support RootBeanDefinition and ChildBeanDefinition.
	 * @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;

	/**
	 * 移除注册表中已注册的 BeanDefinition 实例
	 * Remove the BeanDefinition for the given name.
	 * @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;

	/**
	 * 从注册中取得指定的 BeanDefinition 实例
	 * Return the BeanDefinition for the given bean name.
	 * @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;

	/**
	 * 判断 BeanDefinition 实例是否在注册表中(是否注册)
	 * 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);

	/**
	 * 取得注册表中所有 BeanDefinition 实例的 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();

	/**
	 * 返回注册表中 BeanDefinition 实例的数量
	 * Return the number of beans defined in the registry.
	 * @return the number of beans defined in the registry
	 */
	int getBeanDefinitionCount();

	/**
	 * beanName(标识)是否被占用
	 * 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);
}

再来看BeanDefinitionRegistry的继承关系,DefaultListableBeanFactory赫然在列:

DefaultListableBeanFactory

该类是 BeanDefinitionRegistry 接口的基本实现类,但同时也实现其他了接口的功能,这里只探究下其关于注册 BeanDefinition 实例的相关方法 。

 

首先来看它的成员变量:

// 关键-> 注册表,由 BeanDefinition 的标识 (beanName) 与其实例组成
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

// 标识(beanName)集合
/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

现在进入DefaultBeanDefinitionDocumentReader类的processBeanDefinition方法

/**
 * Process the given bean element, parsing the bean definition
 * and registering it with the registry.
 * 解析BeanDefinition资源
 */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	// BeanDefinitionHolder是对BeanDefinition的封装,即Bean定义的封装类
	//对Document对象中<Bean>元素的解析由BeanDefinitionParserDelegate实现
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// Register the final decorated instance.
			//向Spring IOC容器注册解析得到的BeanDefinition,这是BeanDefinition向IOC容器注册的入口
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// Send registration event.
		// 在完成BeanDefinition注册之后,往容器发送注册完成的事件
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

再来看 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法。该方法的主要作用是调用注册器(DefaultListableBeanFactory)完成注册过程。

/**
 * Register the given bean definition with the given bean factory.
 * @param definitionHolder the bean definition including name and aliases
 * @param registry the bean factory to register with
 * @throws BeanDefinitionStoreException if registration failed
 */
public static void registerBeanDefinition(
		BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
		throws BeanDefinitionStoreException {

	// Register bean definition under primary name.
	// 使用beanName做唯一标识注册
	String beanName = definitionHolder.getBeanName();
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

	// Register aliases for bean name, if any.
	// 注册所有的别名
	String[] aliases = definitionHolder.getAliases();
	if (aliases != null) {
		for (String alias : aliases) {
			registry.registerAlias(beanName, alias);
		}
	}
}

从上面的代码可以看出,解析的beanDefinition都会被注册到BeanDefinitionRegistry类型的实例中,而对于beanDefinition的注册分成了两部分:通过beanName的注册以及通过别名的注册。

1、通过beanName注册BeanDefinition

对于beanDefinition的注册,是将beanDefinition直接放入了map中,以beanName为key。但不仅仅如此,代码如下:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

	/** Resolver to use for checking if a bean definition is an autowire candidate. */
	private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

	/** Map from dependency type to corresponding autowired value. */
	private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

	// 关键-> 注册表,由 BeanDefinition 的标识 (beanName) 与其实例组成
	/** Map of bean definition objects, keyed by bean name. */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

	/** Map from bean name to merged BeanDefinitionHolder. */
	private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);

	/** Map of singleton and non-singleton bean names, keyed by dependency type. */
	private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

	/** Map of singleton-only bean names, keyed by dependency type. */
	private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

	// 标识(beanName)集合
	/** List of bean definition names, in registration order. */
	private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

	/** List of names of manually registered singletons, in registration order. */
	private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

	/** Cached array of bean definition names in case of frozen configuration. */
	@Nullable
	private volatile String[] frozenBeanDefinitionNames;

	/** Whether bean definition metadata may be cached for all beans. */
	private volatile boolean configurationFrozen = false;

	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
		// 校验 beanName 与 beanDefinition 非空
		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		/**
		 * 1、校验 BeanDefinition
		 * 注册前的最后一次校验,这里的校验不同于之前的XML文件校验,
		 * 主要是对于AbstractBeanDefinition属性中的lookup-method属性和replaced-method属性对应的重写方法是否存在并且合法,
		 * 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法根本不存在
		 */
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		// 2、从缓存中获取指定 beanName 的 BeanDefinition
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		//3、看看beanName是否已经存在容器里,存在则表明已经被注册过
		if (existingDefinition != null) {
			// 如果存在但是不允许覆盖,抛出异常
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			// 覆盖 beanDefinition 大于 被覆盖的 beanDefinition 的 ROLE ,打印 info 日志
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			// 覆盖 beanDefinition 与 被覆盖的 beanDefinition 不相同,打印 debug 日志
			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 {
				// 其它,打印 debug 日志
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			// 允许覆盖,直接覆盖原有的 BeanDefinition 到 beanDefinit 大专栏  注册BeanDefinitions-下ionMap 中。
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		//4、如果未存在
		else {
			// 检测创建 Bean 阶段是否已经开启,如果开启了则需要对 beanDefinitionMap 进行并发控制
			if (hasBeanCreationStarted()) {
				// beanDefinitionMap 为全局变量,避免并发情况
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					// 添加BeanDefinition 到 beanDefinitionMap 中。
					this.beanDefinitionMap.put(beanName, beanDefinition);
					// 添加 beanName 到 beanDefinitionNames 中
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					// 从 manualSingletonNames 移除 beanName
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
				// 添加 BeanDefinition 到 beanDefinitionMap 中。
				this.beanDefinitionMap.put(beanName, beanDefinition);
				// 添加 beanName 到 beanDefinitionNames 中
				this.beanDefinitionNames.add(beanName);
				// 从 manualSingletonNames 移除 beanName
				removeManualSingletonName(beanName);
			}
			//将注册期间被冻结的BeanDefinition的名字列表清除掉
			this.frozenBeanDefinitionNames = null;
		}
		// 5、重新设置 beanName 对应的缓存
		//检查是否有同名的BeanDefinition已经在IOC容器中注册
		if (existingDefinition != null || containsSingleton(beanName)) {
			//尝试重置所有已经注册过的BeanDefinition的缓存,包括BeanDefinition
			//的父类以及合并的beanDefinition的缓存,所谓的合并BeanDefinition
			//指的的有parent属性的beandefinition,该BeanDefinition会把parent的
			//BeanDefinition属性合并在一块
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}
}

上面的代码中我们看到,在对于bean的注册处理方式上,主要进行了几个步骤:

  • 1、对AbstractBeanDefinition的校验。在解析XML文件的时候我们提过校验,但是此校验非彼校验,之前的校验是针对XML格式的校验,而此时的校验是针对AbstractBeanDefinition的methodOverrides属性的。
  • 2、对beanName已经注册的情况的处理。如果设置了不允许bean的覆盖,则需要抛出异常,否则直接覆盖。
  • 3、加入map缓存。
  • 4、清楚解析之前留下的对应beanName的缓存。

2、通过别名注册BeanDefinition

在理解了注册bean的原理后,理解注册别名的原理就容易多了。

先看别名注册接口AliasRegistry

public interface AliasRegistry {

	/**
	 * 注册表中给name注册一个别名alias
	 * Given a name, register an alias for it.
	 * @param name the canonical name
	 * @param alias the alias to be registered
	 * @throws IllegalStateException if the alias is already in use
	 * and may not be overridden
	 */
	void registerAlias(String name, String alias);

	/**
	 * 移除注册表中的别名alias
	 * Remove the specified alias from this registry.
	 * @param alias the alias to remove
	 * @throws IllegalStateException if no such alias was found
	 */
	void removeAlias(String alias);

	/**
	 * 校验注册表中是否存在别名name
	 * Determine whether the given name is defined as an alias
	 * (as opposed to the name of an actually registered component).
	 * @param name the name to check
	 * @return whether the given name is an alias
	 */
	boolean isAlias(String name);

	/**
	 * 在注册表中获取给定那么的所有别名信息
	 * Return the aliases for the given name, if defined.
	 * @param name the name to check for aliases
	 * @return the aliases, or an empty array if none
	 */
	String[] getAliases(String name);

}

接着跟进registry.registerAlias(beanName, alias)

public class SimpleAliasRegistry implements AliasRegistry {

	//别名-规范名称的映射MAP,用于存储注册信息(内存注册表)
	/** Map from alias to canonical name. */
	private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

	//注册表中注册别名
	@Override
	public void registerAlias(String name, String alias) {
		Assert.hasText(name, "'name' must not be empty");
		Assert.hasText(alias, "'alias' must not be empty");
		//锁注册表
		//因为CurrentHashMap只有put和remove是线程安全的
		//此处要包装对CurrentHashMap的复合操作线程安全
		synchronized (this.aliasMap) {
			// 如果beanName与alias相同的话不记录alias,并删除对应的alias
			if (alias.equals(name)) {
				//如果别名与名字相同,则在Map中移除
				this.aliasMap.remove(alias);
				if (logger.isDebugEnabled()) {
					logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
				}
			}
			else {
				//获取当前别名在注册表中的规范名称
				String registeredName = this.aliasMap.get(alias);
				if (registeredName != null) {
					//规范名称存在,不需要注册,返回
					if (registeredName.equals(name)) {
						// An existing alias - no need to re-register
						return;
					}
					//判断是否允许重写注册
					if (!allowAliasOverriding()) {
						throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
								name + "': It is already registered for name '" + registeredName + "'.");
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
								registeredName + "' with new target name '" + name + "'");
					}
				}
				// // 校验规范名称是否指向当前别名的
				checkForAliasCircle(name, alias);
				// 注册表注册别名与规范名称的映射
				this.aliasMap.put(alias, name);
				if (logger.isTraceEnabled()) {
					logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
				}
			}
		}
	}
}

由以上代码中可以得知注册alias的步骤如下:

  • 1、beanName与alias相同情况处理。若alias和beanName名称相同则不需要处理并删除原有的alias。
  • 2、alias覆盖处理。若aliasName已经使用并已经指向了另一beanName则需要用户的设置进行处理。
  • 3、alias循环检查。当A -> B存在时,若再次出现 A -> C -> B时候则会抛出异常。
  • 4、注册alias。

SimpleAliasRegistry的其他方法

public class SimpleAliasRegistry implements AliasRegistry {

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

	//别名-规范名称的映射MAP,用于存储注册信息(内存注册表)
	/** Map from alias to canonical name. */
	private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);


	//注册表中注册别名
	@Override
	public void registerAlias(String name, String alias) {
		Assert.hasText(name, "'name' must not be empty");
		Assert.hasText(alias, "'alias' must not be empty");
		//锁注册表
		//因为CurrentHashMap只有put和remove是线程安全的
		//此处要包装对CurrentHashMap的复合操作线程安全
		synchronized (this.aliasMap) {
			// 如果beanName与alias相同的话不记录alias,并删除对应的alias
			if (alias.equals(name)) {
				//如果别名与名字相同,则在Map中移除
				this.aliasMap.remove(alias);
				if (logger.isDebugEnabled()) {
					logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
				}
			}
			else {
				//获取当前别名在注册表中的规范名称
				String registeredName = this.aliasMap.get(alias);
				if (registeredName != null) {
					//规范名称存在,不需要注册,返回
					if (registeredName.equals(name)) {
						// An existing alias - no need to re-register
						return;
					}
					//判断是否允许重写注册
					if (!allowAliasOverriding()) {
						throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
								name + "': It is already registered for name '" + registeredName + "'.");
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
								registeredName + "' with new target name '" + name + "'");
					}
				}
				// // 校验规范名称是否指向当前别名的
				checkForAliasCircle(name, alias);
				// 注册表注册别名与规范名称的映射
				this.aliasMap.put(alias, name);
				if (logger.isTraceEnabled()) {
					logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
				}
			}
		}
	}

	/**
	 * 是否允许重写注册表别名信息,默认true
	 * Determine whether alias overriding is allowed.
	 * <p>Default is {@code true}.
	 */
	protected boolean allowAliasOverriding() {
		return true;
	}

	/**
	 * 校验给定的name-alias映射是否已在注册表aliasMap中
	 * Determine whether the given name has the given alias registered.
	 * @param name the name to check
	 * @param alias the alias to look for
	 * @since 4.2.1
	 */
	public boolean hasAlias(String name, String alias) {
		//获取注册表中单映射的规范名称name
		String registeredName = this.aliasMap.get(alias);
		return ObjectUtils.nullSafeEquals(registeredName, name) || (registeredName != null
				&& hasAlias(name, registeredName));
	}

	/**
	 *  移除别名,在注册表aliasMap中
	 * @param alias the alias to remove
	 */
	@Override
	public void removeAlias(String alias) {
		synchronized (this.aliasMap) {
			String name = this.aliasMap.remove(alias);
			if (name == null) {
				throw new IllegalStateException("No alias '" + alias + "' registered");
			}
		}
	}

	//校验是否包含给定的别名,在注册表中
	@Override
	public boolean isAlias(String name) {
		return this.aliasMap.containsKey(name);
	}

	// 在注册表获取给定规范名称的所有别名信息
	@Override
	public String[] getAliases(String name) {
		List<String> result = new ArrayList<>();
		synchronized (this.aliasMap) {
			retrieveAliases(name, result);
		}
		return StringUtils.toStringArray(result);
	}

	/**
	 * Transitively retrieve all aliases for the given name.
	 * @param name the target name to find aliases for
	 * @param result the resulting aliases list
	 */
	private void retrieveAliases(String name, List<String> result) {
		this.aliasMap.forEach((alias, registeredName) -> {
			//判断当前别名的规范名称是否为要查询的
			if (registeredName.equals(name)) {
				result.add(alias);
				//递归查询循环引用的别名
				retrieveAliases(alias, result);
			}
		});
	}

	/**
	 * Resolve all alias target names and aliases registered in this
	 * registry, applying the given {@link StringValueResolver} to them.
	 * <p>The value resolver may for example resolve placeholders
	 * in target bean names and even in alias names.
	 * @param valueResolver the StringValueResolver to apply
	 */
	public void resolveAliases(StringValueResolver valueResolver) {
		Assert.notNull(valueResolver, "StringValueResolver must not be null");
		synchronized (this.aliasMap) {
			Map<String, String> aliasCopy = new HashMap<>(this.aliasMap);
			aliasCopy.forEach((alias, registeredName) -> {
				String resolvedAlias = valueResolver.resolveStringValue(alias);
				String resolvedName = valueResolver.resolveStringValue(registeredName);
				if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) {
					this.aliasMap.remove(alias);
				}
				else if (!resolvedAlias.equals(alias)) {
					String existingName = this.aliasMap.get(resolvedAlias);
					if (existingName != null) {
						if (existingName.equals(resolvedName)) {
							// Pointing to existing alias - just remove placeholder
							this.aliasMap.remove(alias);
							return;
						}
						throw new IllegalStateException(
								"Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias +
								"') for name '" + resolvedName + "': It is already registered for name '" +
								registeredName + "'.");
					}
					checkForAliasCircle(resolvedName, resolvedAlias);
					this.aliasMap.remove(alias);
					this.aliasMap.put(resolvedAlias, resolvedName);
				}
				else if (!registeredName.equals(resolvedName)) {
					this.aliasMap.put(alias, resolvedName);
				}
			});
		}
	}

	/**
	 * 校验给定的名称是否指向别名,不指向异常抛出
	 * Check whether the given name points back to the given alias as an alias
	 * in the other direction already, catching a circular reference upfront
	 * and throwing a corresponding IllegalStateException.
	 * @param name the candidate name
	 * @param alias the candidate alias
	 * @see #registerAlias
	 * @see #hasAlias
	 */
	protected void checkForAliasCircle(String name, String alias) {
		if (hasAlias(alias, name)) {
			throw new IllegalStateException("Cannot register alias '" + alias +
					"' for name '" + name + "': Circular reference - '" +
					name + "' is a direct or indirect alias for '" + alias + "' already");
		}
	}

	/**
	 * 根据给定的别名获取规范名称
	 * Determine the raw name, resolving aliases to canonical names.
	 * @param name the user-specified name
	 * @return the transformed name
	 */
	public String canonicalName(String name) {
		String canonicalName = name;
		// Handle aliasing...
		String resolvedName;
		do {
			//获取给定别名的规范名称,获取到跳出循环
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}

}

SimpleBeanDefinitionRegistry 为BeanDefinitionRegistry的默认实现,同时继承AliasRegistry的默认实现SimpleAliasRegistry,所以它总共维护了两个注册表aliasMap(别名注册表)与beanDefinitionMap(bean描述注册表),到此AliasRegistry接口功能的主要实现以及扩展接口的主要实现通过源码已清晰展示

 

参考: https://www.cnblogs.com/monkey0307/p/8509701.html

https://www.cnblogs.com/warehouse/p/9380473.html

https://www.cnblogs.com/moxiaotao/p/9349549.html

https://www.cnblogs.com/loongk/p/12297193.html

https://blog.csdn.net/whoyou223/article/details/78205803

标签:name,beanName,alias,bean,String,Spring5,IOC,BeanDefinition
From: https://blog.51cto.com/u_14014612/5995698

相关文章

  • Spring IOC官方文档学习笔记(七)之Bean Definition继承
    1.BeanDefinition继承(1)Spring中的bean存在层级关系,我们可以定义子bean来继承或覆盖父bean中的某些属性,从而节省编码,在此处Spring运用到了模板设计模式,如下所示//自定......
  • BeanDefinition基本定义
    BeanDefinition定义了Bean的基本元信息、生命周期方法等。描述了SpringBean的基本信息。其初始化方法主要有以下两种方式:本文案例也是基于SpringFramework5.2.2.RELEAS......
  • ioctl(skfd, request, pwrq)
    /*------------------------------------------------------------------*//**WrappertoextractsomeWirelessParameteroutofthedriver*/staticinlinein......
  • Spring bean注入问题:NoUniqueBeanDefinitionException解决方案归纳
    引言   spring实现的bean自动注入在项目开发中是一个经常使用到的功能,但自动装配两个或多个bean时,会抛出NoUniqueBeanDefinitionException:Noqualifyingbeanoftyp......
  • spring5框架
    概述:Spring是轻量级的开源的JavaEE框架Spring可以解决企业应用开发的复杂性Spring有两个核心部分:IOC和AOPIOC:控制反转,把创建对象过程交给Spring进行管理AOP:面向切面......
  • Spring IOC官方文档学习笔记(六)之自定义bean的特性
    1.生命周期回调(1)如果我们想要介入bean的生命周期,可通过实现spring中的InitializingBean和DisposableBean接口来达到这一目的,spring会调用InitializingBean中的afterPro......
  • spring项目中添加@Transactional注解后出现NoSuchBeanDefinitionException异常的解决
    https://blog.csdn.net/qq_37059367/article/details/83145779数据库配置文件中修改配置文件里这一句<tx:annotation-driventransaction-manager="transactionManager"/......
  • spring 基础知识-- IOC 和 DI 的配置和使用。
    目录​​一、基本概念​​​​二、Spring核心概念 ​​​​1、问题分析​​​​2、IOC、IOC容器、Bean、DI​​​​3、IOC入门案例​​​​4、DI入门案例​​​​三、IO......
  • Spring注解:使用注解的方式完成IOC
    补充:xml配置最开始(Spring1.x),Spring都是通过xml配置控制层(controller)--业务逻辑层(service)--dao层--数据源的关系,但是比较复杂Spring2.x的时候,随着JDK1.5支持注解的方式,......
  • Spring简介及IOC使用
     Spring介绍官网:https://spring.io/Spring是一个对象的容器,负责管理对象的创建、销毁,以及对象的属性注入,对象的之间的依赖关系。Spring可以整合其它框架,他基于IOC和AO......