Spring源码分析-IOC之BeanDefinitionHolder
2019-03-28 23:15
447 查看
BeanDefinitionHolder顾名思义就是对BeanDefinition的持有,同时持有的包括BeanDefinition的名称和别名,BeanDefinition我们在前面的文章已经介绍过Spring源码分析-IOC之BeanDefinition,BeanDefinitionHolder同时实现了BeanMetadataElement,BeanMetadataElement我们在前面也已经介绍过Spring源码分析-IOC之BeanMetadataElement,有兴趣的同学可以看下,下面我们先看下BeanDefinitionHolder的源码:
[code]//实现了BeanMetadataElement接口 public class BeanDefinitionHolder implements BeanMetadataElement { //持有BeanDefinition private final BeanDefinition beanDefinition; //BeanDefinition的名称 private final String beanName; //BeanDefinition的别名 //Nullable注解表示该属性可以为空 @Nullable private final String[] aliases; //根据bean的名称和beanDefinition初始化BeanDefinitionHolder public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) { //此次实际是调用的另外一个构造方法 this(beanDefinition, beanName, null); } //根据bean的名称和beanDefinition,别名aliases初始化BeanDefinitionHolder //别名aliases可以为空 public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) { Assert.notNull(beanDefinition, "BeanDefinition must not be null"); Assert.notNull(beanName, "Bean name must not be null"); this.beanDefinition = beanDefinition; this.beanName = beanName; this.aliases = aliases; } //根据指定的BeanDefinitionHolder 复制一个新的BeanDefinitionHolder //此处不是深克隆 public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) { Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null"); this.beanDefinition = beanDefinitionHolder.getBeanDefinition(); this.beanName = beanDefinitionHolder.getBeanName(); this.aliases = beanDefinitionHolder.getAliases(); } //获取BeanDefinition public BeanDefinition getBeanDefinition() { return this.beanDefinition; } //获取bean的名称 public String getBeanName() { return this.beanName; } //获取别名 @Nullable public String[] getAliases() { return this.aliases; } //获取beanDefinition的源对象,实现了BeanMetadataElement @Override @Nullable public Object getSource() { return this.beanDefinition.getSource(); } //判断指定的名称与beanName或者别名身份匹配 public boolean matchesName(@Nullable String candidateName) { return (candidateName != null && (candidateName.equals(this.beanName) || candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) || ObjectUtils.containsElement(this.aliases, candidateName))); } //返回一个描述包括bean的名称和所有的别名 public String getShortDescription() { StringBuilder sb = new StringBuilder(); sb.append("Bean definition with name '").append(this.beanName).append("'"); if (this.aliases != null) { sb.append(" and aliases [").append(StringUtils.arrayToCommaDelimitedString(this.aliases)).append("]"); } return sb.toString(); } //返回一个长描述包括名称,别名已经beanDefinition的内容 public String getLongDescription() { StringBuilder sb = new StringBuilder(getShortDescription()); sb.append(": ").append(this.beanDefinition); return sb.toString(); } //重写toString方法 @Override public String toString() { return getLongDescription(); } //重写equals方法 @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof BeanDefinitionHolder)) { return false; } BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other; return this.beanDefinition.equals(otherHolder.beanDefinition) && this.beanName.equals(otherHolder.beanName) && ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases); } //重写hashCode方法 @Override public int hashCode() { int hashCode = this.beanDefinition.hashCode(); hashCode = 29 * hashCode + this.beanName.hashCode(); hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases); return hashCode; } }
下面我们继续看BeanDefinitionHolder在spring中的应用,DefaultBeanDefinitionDocumentReader中在解析默认的标签bean元素的时候 :
[code]private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { //此处解析bean元素 processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
接下来processBeanDefinition方法:
[code]protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //根据bean元素创建BeanDefinitionHolder 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)); } }
继续往下看BeanDefinitionParserDelegate中的parseBeanDefinitionElement:
[code] public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); } @Nullable public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { String id = ele.getAttribute(ID_ATTRIBUTE); String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List<String> aliases = new ArrayList<>(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isTraceEnabled()) { logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } //解析bean元素的属性,创建beanDefinition AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { 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 && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } 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; }
以上方法实际上就是解析bean元素,创建beanDefinition,然后将beanDefinition,beanName,aliases创建为BeanDefinitionHolder,我们继续回到processBeanDefinition方法中:
[code]protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 根据BeanDefinitionHolder 注册beanDefinition BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } //此处根据BeanDefinitionHolder 创建一个BeanComponentDefinition getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
我们继续看下BeanDefinitionReaderUtils.registerBeanDefinition的方法:
[code]public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // 就是根据BeanDefinitionHolder 的属性注册 //注册的具体内容细节我们将会在后面将 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); } } }
以上就是BeanDefinitionHolder 在spring的主要功能。
小结:我们在开发中也可以借鉴BeanDefinitionHolder 这种方式,更好的封装我们的数据。
相关文章推荐
- 【spring源码分析】BeanDefinitionRegistryPostProcessor接口可自定义bean加入IOC
- Spring源码学习--BeanDefinitionHolder
- 【Spring源码--IOC容器的实现】(三)BeanDefinition的载入和解析【I】
- 小读spring ioc源码(五)——BeanDefinitionDocumentReader
- SpringBoot源码分析之BeanDefinitionLoader注册主Configuration的Java配置类
- Spring源码阅读--BeanDefinition 在 IOC 容器中的注册
- 【Spring源码--IOC容器的实现】(四)BeanDefinition的注册
- Spring源码分析-BeanDefinition加载、解析和注册
- Spring源码解析-BeanDefinition在IOC容器中的注册(三)
- 【Spring源码--IOC容器的实现】(二)BeanDefinition的Resource定位
- Ioc容器beanDefinition-Spring 源码系列(1)
- Spring IOC容器分析(2) -- BeanDefinition
- Spring源码阅读之IoC容器初始化2 -- BeanDefinition载入与解析
- 【Spring源码--IOC容器的实现】(三)BeanDefinition的载入和解析【II】
- spring IOC源码学习(二):BeanDefinition资源加载
- Spring源码阅读之IoC容器初始化3 -- BeanDefinition在IoC容器中的注册
- spring源码学习之四 BeanDefinitionParserDelegate分析
- 小读spring ioc源码(四)——BeanDefinitionReader
- 白话Spring源码(六):BeanDefinition的注册过程
- 深探spring系列-----ioc初始化(1)BeanDefinition的Resource定位