001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory.config; 018 019import org.springframework.beans.BeanMetadataElement; 020import org.springframework.beans.factory.BeanFactoryUtils; 021import org.springframework.util.Assert; 022import org.springframework.util.ObjectUtils; 023import org.springframework.util.StringUtils; 024 025/** 026 * Holder for a BeanDefinition with name and aliases. 027 * Can be registered as a placeholder for an inner bean. 028 * 029 * <p>Can also be used for programmatic registration of inner bean 030 * definitions. If you don't care about BeanNameAware and the like, 031 * registering RootBeanDefinition or ChildBeanDefinition is good enough. 032 * 033 * @author Juergen Hoeller 034 * @since 1.0.2 035 * @see org.springframework.beans.factory.BeanNameAware 036 * @see org.springframework.beans.factory.support.RootBeanDefinition 037 * @see org.springframework.beans.factory.support.ChildBeanDefinition 038 */ 039public class BeanDefinitionHolder implements BeanMetadataElement { 040 041 private final BeanDefinition beanDefinition; 042 043 private final String beanName; 044 045 private final String[] aliases; 046 047 048 /** 049 * Create a new BeanDefinitionHolder. 050 * @param beanDefinition the BeanDefinition to wrap 051 * @param beanName the name of the bean, as specified for the bean definition 052 */ 053 public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) { 054 this(beanDefinition, beanName, null); 055 } 056 057 /** 058 * Create a new BeanDefinitionHolder. 059 * @param beanDefinition the BeanDefinition to wrap 060 * @param beanName the name of the bean, as specified for the bean definition 061 * @param aliases alias names for the bean, or {@code null} if none 062 */ 063 public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, String[] aliases) { 064 Assert.notNull(beanDefinition, "BeanDefinition must not be null"); 065 Assert.notNull(beanName, "Bean name must not be null"); 066 this.beanDefinition = beanDefinition; 067 this.beanName = beanName; 068 this.aliases = aliases; 069 } 070 071 /** 072 * Copy constructor: Create a new BeanDefinitionHolder with the 073 * same contents as the given BeanDefinitionHolder instance. 074 * <p>Note: The wrapped BeanDefinition reference is taken as-is; 075 * it is {@code not} deeply copied. 076 * @param beanDefinitionHolder the BeanDefinitionHolder to copy 077 */ 078 public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) { 079 Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null"); 080 this.beanDefinition = beanDefinitionHolder.getBeanDefinition(); 081 this.beanName = beanDefinitionHolder.getBeanName(); 082 this.aliases = beanDefinitionHolder.getAliases(); 083 } 084 085 086 /** 087 * Return the wrapped BeanDefinition. 088 */ 089 public BeanDefinition getBeanDefinition() { 090 return this.beanDefinition; 091 } 092 093 /** 094 * Return the primary name of the bean, as specified for the bean definition. 095 */ 096 public String getBeanName() { 097 return this.beanName; 098 } 099 100 /** 101 * Return the alias names for the bean, as specified directly for the bean definition. 102 * @return the array of alias names, or {@code null} if none 103 */ 104 public String[] getAliases() { 105 return this.aliases; 106 } 107 108 /** 109 * Expose the bean definition's source object. 110 * @see BeanDefinition#getSource() 111 */ 112 @Override 113 public Object getSource() { 114 return this.beanDefinition.getSource(); 115 } 116 117 /** 118 * Determine whether the given candidate name matches the bean name 119 * or the aliases stored in this bean definition. 120 */ 121 public boolean matchesName(String candidateName) { 122 return (candidateName != null && (candidateName.equals(this.beanName) || 123 candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) || 124 ObjectUtils.containsElement(this.aliases, candidateName))); 125 } 126 127 128 /** 129 * Return a friendly, short description for the bean, stating name and aliases. 130 * @see #getBeanName() 131 * @see #getAliases() 132 */ 133 public String getShortDescription() { 134 StringBuilder sb = new StringBuilder(); 135 sb.append("Bean definition with name '").append(this.beanName).append("'"); 136 if (this.aliases != null) { 137 sb.append(" and aliases [").append(StringUtils.arrayToCommaDelimitedString(this.aliases)).append("]"); 138 } 139 return sb.toString(); 140 } 141 142 /** 143 * Return a long description for the bean, including name and aliases 144 * as well as a description of the contained {@link BeanDefinition}. 145 * @see #getShortDescription() 146 * @see #getBeanDefinition() 147 */ 148 public String getLongDescription() { 149 StringBuilder sb = new StringBuilder(getShortDescription()); 150 sb.append(": ").append(this.beanDefinition); 151 return sb.toString(); 152 } 153 154 /** 155 * This implementation returns the long description. Can be overridden 156 * to return the short description or any kind of custom description instead. 157 * @see #getLongDescription() 158 * @see #getShortDescription() 159 */ 160 @Override 161 public String toString() { 162 return getLongDescription(); 163 } 164 165 166 @Override 167 public boolean equals(Object other) { 168 if (this == other) { 169 return true; 170 } 171 if (!(other instanceof BeanDefinitionHolder)) { 172 return false; 173 } 174 BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other; 175 return this.beanDefinition.equals(otherHolder.beanDefinition) && 176 this.beanName.equals(otherHolder.beanName) && 177 ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases); 178 } 179 180 @Override 181 public int hashCode() { 182 int hashCode = this.beanDefinition.hashCode(); 183 hashCode = 29 * hashCode + this.beanName.hashCode(); 184 hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases); 185 return hashCode; 186 } 187 188}