Spring Bean加载流程分析(通过 XML 方式加载)( 九 )


对于 alias 标签的处理我们并不关心 , 在实际应用中这样处理少之又少 , 我们这里选择跳过 。 直接看 processBeanDefinition 这个方法的实现 。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);try {// Register the final decorated instance.BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());}catch (BeanDefinitionStoreException ex) {getReaderContext().error("Failed to register bean definition with name '" +bdHolder.getBeanName() + "'", ele, ex);}// Send registration event.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));}}复制代码该方法的主要作用便是从给定的 Bean Element 标签中解析出 BeanDefinition 并将其放入到给定的 registry 中 , 也就是我们声明的 DefaultListableBeanFactory 中 。 看看 delegate.parseBeanDefinitionElement 是如何解析的 。
@Nullablepublic BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {// 从标签中获取到 id 属性String id = ele.getAttribute(ID_ATTRIBUTE);// 从标签中获取到 name 属性String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);List aliases = new ArrayList<>();// 对别名的处理if (StringUtils.hasLength(nameAttr)) {String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);aliases.addAll(Arrays.asList(nameArr));}// 将 id 作为 bean 的名称String beanName = id;// 如果 beanName 为空 , 则从别名的数组中取出第一个元素作为 beanNameif (!StringUtils.hasText(beanName)}// 检查名称的唯一性if (containingBean == null) {checkNameUniqueness(beanName, aliases, ele);}// 解析出 bean 的定义AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);if (beanDefinition != null) {// 如果解析出的 Bean 没有 beanName , 那么会自动给该 bean 生成一个名称if (!StringUtils.hasText(beanName)) {try {if (containingBean != null) {beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);}else {beanName = this.readerContext.generateBeanName(beanDefinition);// Register an alias for the plain bean class name, if still possible,// if the generator returned the class name plus a suffix.// This is expected for Spring 1.2/2.0 backwards compatibility.String beanClassName = beanDefinition.getBeanClassName();if (beanClassName != null}}if (logger.isTraceEnabled()) {logger.trace("Neither XML 'id' nor 'name' specified - " +"using generated bean name [" + beanName + "]");}}catch (Exception ex) {error(ex.getMessage(), ele);return null;}}String[] aliasesArray = StringUtils.toStringArray(aliases);// 返回一个 BeanDefinitionHolder 对象return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);}return null;}复制代码该方法做了如下几件事