View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.beans.factory.support;
18  
19  import java.beans.PropertyEditor;
20  import java.security.AccessControlContext;
21  import java.security.AccessController;
22  import java.security.PrivilegedAction;
23  import java.security.PrivilegedActionException;
24  import java.security.PrivilegedExceptionAction;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.HashSet;
30  import java.util.LinkedHashMap;
31  import java.util.LinkedHashSet;
32  import java.util.LinkedList;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.concurrent.ConcurrentHashMap;
37  
38  import org.springframework.beans.BeanUtils;
39  import org.springframework.beans.BeanWrapper;
40  import org.springframework.beans.BeansException;
41  import org.springframework.beans.PropertyEditorRegistrar;
42  import org.springframework.beans.PropertyEditorRegistry;
43  import org.springframework.beans.PropertyEditorRegistrySupport;
44  import org.springframework.beans.SimpleTypeConverter;
45  import org.springframework.beans.TypeConverter;
46  import org.springframework.beans.TypeMismatchException;
47  import org.springframework.beans.factory.BeanCreationException;
48  import org.springframework.beans.factory.BeanCurrentlyInCreationException;
49  import org.springframework.beans.factory.BeanDefinitionStoreException;
50  import org.springframework.beans.factory.BeanFactory;
51  import org.springframework.beans.factory.BeanFactoryUtils;
52  import org.springframework.beans.factory.BeanIsAbstractException;
53  import org.springframework.beans.factory.BeanIsNotAFactoryException;
54  import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
55  import org.springframework.beans.factory.CannotLoadBeanClassException;
56  import org.springframework.beans.factory.FactoryBean;
57  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
58  import org.springframework.beans.factory.ObjectFactory;
59  import org.springframework.beans.factory.SmartFactoryBean;
60  import org.springframework.beans.factory.config.BeanDefinition;
61  import org.springframework.beans.factory.config.BeanDefinitionHolder;
62  import org.springframework.beans.factory.config.BeanExpressionContext;
63  import org.springframework.beans.factory.config.BeanExpressionResolver;
64  import org.springframework.beans.factory.config.BeanPostProcessor;
65  import org.springframework.beans.factory.config.ConfigurableBeanFactory;
66  import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
67  import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
68  import org.springframework.beans.factory.config.Scope;
69  import org.springframework.core.DecoratingClassLoader;
70  import org.springframework.core.NamedThreadLocal;
71  import org.springframework.core.convert.ConversionService;
72  import org.springframework.util.Assert;
73  import org.springframework.util.ClassUtils;
74  import org.springframework.util.ObjectUtils;
75  import org.springframework.util.StringUtils;
76  import org.springframework.util.StringValueResolver;
77  
78  /**
79   * Abstract base class for {@link org.springframework.beans.factory.BeanFactory}
80   * implementations, providing the full capabilities of the
81   * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI.
82   * Does <i>not</i> assume a listable bean factory: can therefore also be used
83   * as base class for bean factory implementations which obtain bean definitions
84   * from some backend resource (where bean definition access is an expensive operation).
85   *
86   * <p>This class provides a singleton cache (through its base class
87   * {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry},
88   * singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean}
89   * handling, aliases, bean definition merging for child bean definitions,
90   * and bean destruction ({@link org.springframework.beans.factory.DisposableBean}
91   * interface, custom destroy methods). Furthermore, it can manage a bean factory
92   * hierarchy (delegating to the parent in case of an unknown bean), through implementing
93   * the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface.
94   *
95   * <p>The main template methods to be implemented by subclasses are
96   * {@link #getBeanDefinition} and {@link #createBean}, retrieving a bean definition
97   * for a given bean name and creating a bean instance for a given bean definition,
98   * respectively. Default implementations of those operations can be found in
99   * {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}.
100  *
101  * @author Rod Johnson
102  * @author Juergen Hoeller
103  * @author Costin Leau
104  * @author Chris Beams
105  * @since 15 April 2001
106  * @see #getBeanDefinition
107  * @see #createBean
108  * @see AbstractAutowireCapableBeanFactory#createBean
109  * @see DefaultListableBeanFactory#getBeanDefinition
110  */
111 public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
112 
113 	/** Parent bean factory, for bean inheritance support */
114 	private BeanFactory parentBeanFactory;
115 
116 	/** ClassLoader to resolve bean class names with, if necessary */
117 	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
118 
119 	/** ClassLoader to temporarily resolve bean class names with, if necessary */
120 	private ClassLoader tempClassLoader;
121 
122 	/** Whether to cache bean metadata or rather reobtain it for every access */
123 	private boolean cacheBeanMetadata = true;
124 
125 	/** Resolution strategy for expressions in bean definition values */
126 	private BeanExpressionResolver beanExpressionResolver;
127 
128 	/** Spring ConversionService to use instead of PropertyEditors */
129 	private ConversionService conversionService;
130 
131 	/** Custom PropertyEditorRegistrars to apply to the beans of this factory */
132 	private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
133 			new LinkedHashSet<PropertyEditorRegistrar>(4);
134 
135 	/** A custom TypeConverter to use, overriding the default PropertyEditor mechanism */
136 	private TypeConverter typeConverter;
137 
138 	/** Custom PropertyEditors to apply to the beans of this factory */
139 	private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
140 			new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);
141 
142 	/** String resolvers to apply e.g. to annotation attribute values */
143 	private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();
144 
145 	/** BeanPostProcessors to apply in createBean */
146 	private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
147 
148 	/** Indicates whether any InstantiationAwareBeanPostProcessors have been registered */
149 	private boolean hasInstantiationAwareBeanPostProcessors;
150 
151 	/** Indicates whether any DestructionAwareBeanPostProcessors have been registered */
152 	private boolean hasDestructionAwareBeanPostProcessors;
153 
154 	/** Map from scope identifier String to corresponding Scope */
155 	private final Map<String, Scope> scopes = new LinkedHashMap<String, Scope>(8);
156 
157 	/** Security context used when running with a SecurityManager */
158 	private SecurityContextProvider securityContextProvider;
159 
160 	/** Map from bean name to merged RootBeanDefinition */
161 	private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
162 			new ConcurrentHashMap<String, RootBeanDefinition>(64);
163 
164 	/** Names of beans that have already been created at least once */
165 	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));
166 
167 	/** Names of beans that are currently in creation */
168 	private final ThreadLocal<Object> prototypesCurrentlyInCreation =
169 			new NamedThreadLocal<Object>("Prototype beans currently in creation");
170 
171 
172 	/**
173 	 * Create a new AbstractBeanFactory.
174 	 */
175 	public AbstractBeanFactory() {
176 	}
177 
178 	/**
179 	 * Create a new AbstractBeanFactory with the given parent.
180 	 * @param parentBeanFactory parent bean factory, or {@code null} if none
181 	 * @see #getBean
182 	 */
183 	public AbstractBeanFactory(BeanFactory parentBeanFactory) {
184 		this.parentBeanFactory = parentBeanFactory;
185 	}
186 
187 
188 	//---------------------------------------------------------------------
189 	// Implementation of BeanFactory interface
190 	//---------------------------------------------------------------------
191 
192 	@Override
193 	public Object getBean(String name) throws BeansException {
194 		return doGetBean(name, null, null, false);
195 	}
196 
197 	@Override
198 	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
199 		return doGetBean(name, requiredType, null, false);
200 	}
201 
202 	@Override
203 	public Object getBean(String name, Object... args) throws BeansException {
204 		return doGetBean(name, null, args, false);
205 	}
206 
207 	/**
208 	 * Return an instance, which may be shared or independent, of the specified bean.
209 	 * @param name the name of the bean to retrieve
210 	 * @param requiredType the required type of the bean to retrieve
211 	 * @param args arguments to use when creating a bean instance using explicit arguments
212 	 * (only applied when creating a new instance as opposed to retrieving an existing one)
213 	 * @return an instance of the bean
214 	 * @throws BeansException if the bean could not be created
215 	 */
216 	public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
217 		return doGetBean(name, requiredType, args, false);
218 	}
219 
220 	/**
221 	 * Return an instance, which may be shared or independent, of the specified bean.
222 	 * @param name the name of the bean to retrieve
223 	 * @param requiredType the required type of the bean to retrieve
224 	 * @param args arguments to use when creating a bean instance using explicit arguments
225 	 * (only applied when creating a new instance as opposed to retrieving an existing one)
226 	 * @param typeCheckOnly whether the instance is obtained for a type check,
227 	 * not for actual use
228 	 * @return an instance of the bean
229 	 * @throws BeansException if the bean could not be created
230 	 */
231 	@SuppressWarnings("unchecked")
232 	protected <T> T doGetBean(
233 			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
234 			throws BeansException {
235 
236 		final String beanName = transformedBeanName(name);
237 		Object bean;
238 
239 		// Eagerly check singleton cache for manually registered singletons.
240 		Object sharedInstance = getSingleton(beanName);
241 		if (sharedInstance != null && args == null) {
242 			if (logger.isDebugEnabled()) {
243 				if (isSingletonCurrentlyInCreation(beanName)) {
244 					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
245 							"' that is not fully initialized yet - a consequence of a circular reference");
246 				}
247 				else {
248 					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
249 				}
250 			}
251 			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
252 		}
253 
254 		else {
255 			// Fail if we're already creating this bean instance:
256 			// We're assumably within a circular reference.
257 			if (isPrototypeCurrentlyInCreation(beanName)) {
258 				throw new BeanCurrentlyInCreationException(beanName);
259 			}
260 
261 			// Check if bean definition exists in this factory.
262 			BeanFactory parentBeanFactory = getParentBeanFactory();
263 			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
264 				// Not found -> check parent.
265 				String nameToLookup = originalBeanName(name);
266 				if (args != null) {
267 					// Delegation to parent with explicit args.
268 					return (T) parentBeanFactory.getBean(nameToLookup, args);
269 				}
270 				else {
271 					// No args -> delegate to standard getBean method.
272 					return parentBeanFactory.getBean(nameToLookup, requiredType);
273 				}
274 			}
275 
276 			if (!typeCheckOnly) {
277 				markBeanAsCreated(beanName);
278 			}
279 
280 			try {
281 				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
282 				checkMergedBeanDefinition(mbd, beanName, args);
283 
284 				// Guarantee initialization of beans that the current bean depends on.
285 				String[] dependsOn = mbd.getDependsOn();
286 				if (dependsOn != null) {
287 					for (String dependsOnBean : dependsOn) {
288 						if (isDependent(beanName, dependsOnBean)) {
289 							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
290 									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
291 						}
292 						registerDependentBean(dependsOnBean, beanName);
293 						getBean(dependsOnBean);
294 					}
295 				}
296 
297 				// Create bean instance.
298 				if (mbd.isSingleton()) {
299 					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
300 						@Override
301 						public Object getObject() throws BeansException {
302 							try {
303 								return createBean(beanName, mbd, args);
304 							}
305 							catch (BeansException ex) {
306 								// Explicitly remove instance from singleton cache: It might have been put there
307 								// eagerly by the creation process, to allow for circular reference resolution.
308 								// Also remove any beans that received a temporary reference to the bean.
309 								destroySingleton(beanName);
310 								throw ex;
311 							}
312 						}
313 					});
314 					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
315 				}
316 
317 				else if (mbd.isPrototype()) {
318 					// It's a prototype -> create a new instance.
319 					Object prototypeInstance = null;
320 					try {
321 						beforePrototypeCreation(beanName);
322 						prototypeInstance = createBean(beanName, mbd, args);
323 					}
324 					finally {
325 						afterPrototypeCreation(beanName);
326 					}
327 					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
328 				}
329 
330 				else {
331 					String scopeName = mbd.getScope();
332 					final Scope scope = this.scopes.get(scopeName);
333 					if (scope == null) {
334 						throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
335 					}
336 					try {
337 						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
338 							@Override
339 							public Object getObject() throws BeansException {
340 								beforePrototypeCreation(beanName);
341 								try {
342 									return createBean(beanName, mbd, args);
343 								}
344 								finally {
345 									afterPrototypeCreation(beanName);
346 								}
347 							}
348 						});
349 						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
350 					}
351 					catch (IllegalStateException ex) {
352 						throw new BeanCreationException(beanName,
353 								"Scope '" + scopeName + "' is not active for the current thread; " +
354 								"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
355 								ex);
356 					}
357 				}
358 			}
359 			catch (BeansException ex) {
360 				cleanupAfterBeanCreationFailure(beanName);
361 				throw ex;
362 			}
363 		}
364 
365 		// Check if required type matches the type of the actual bean instance.
366 		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
367 			try {
368 				return getTypeConverter().convertIfNecessary(bean, requiredType);
369 			}
370 			catch (TypeMismatchException ex) {
371 				if (logger.isDebugEnabled()) {
372 					logger.debug("Failed to convert bean '" + name + "' to required type [" +
373 							ClassUtils.getQualifiedName(requiredType) + "]", ex);
374 				}
375 				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
376 			}
377 		}
378 		return (T) bean;
379 	}
380 
381 	@Override
382 	public boolean containsBean(String name) {
383 		String beanName = transformedBeanName(name);
384 		if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
385 			return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
386 		}
387 		// Not found -> check parent.
388 		BeanFactory parentBeanFactory = getParentBeanFactory();
389 		return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
390 	}
391 
392 	@Override
393 	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
394 		String beanName = transformedBeanName(name);
395 
396 		Object beanInstance = getSingleton(beanName, false);
397 		if (beanInstance != null) {
398 			if (beanInstance instanceof FactoryBean) {
399 				return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean<?>) beanInstance).isSingleton());
400 			}
401 			else {
402 				return !BeanFactoryUtils.isFactoryDereference(name);
403 			}
404 		}
405 		else if (containsSingleton(beanName)) {
406 			return true;
407 		}
408 
409 		else {
410 			// No singleton instance found -> check bean definition.
411 			BeanFactory parentBeanFactory = getParentBeanFactory();
412 			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
413 				// No bean definition found in this factory -> delegate to parent.
414 				return parentBeanFactory.isSingleton(originalBeanName(name));
415 			}
416 
417 			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
418 
419 			// In case of FactoryBean, return singleton status of created object if not a dereference.
420 			if (mbd.isSingleton()) {
421 				if (isFactoryBean(beanName, mbd)) {
422 					if (BeanFactoryUtils.isFactoryDereference(name)) {
423 						return true;
424 					}
425 					FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
426 					return factoryBean.isSingleton();
427 				}
428 				else {
429 					return !BeanFactoryUtils.isFactoryDereference(name);
430 				}
431 			}
432 			else {
433 				return false;
434 			}
435 		}
436 	}
437 
438 	@Override
439 	public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
440 		String beanName = transformedBeanName(name);
441 
442 		BeanFactory parentBeanFactory = getParentBeanFactory();
443 		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
444 			// No bean definition found in this factory -> delegate to parent.
445 			return parentBeanFactory.isPrototype(originalBeanName(name));
446 		}
447 
448 		RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
449 		if (mbd.isPrototype()) {
450 			// In case of FactoryBean, return singleton status of created object if not a dereference.
451 			return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd));
452 		}
453 		else {
454 			// Singleton or scoped - not a prototype.
455 			// However, FactoryBean may still produce a prototype object...
456 			if (BeanFactoryUtils.isFactoryDereference(name)) {
457 				return false;
458 			}
459 			if (isFactoryBean(beanName, mbd)) {
460 				final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
461 				if (System.getSecurityManager() != null) {
462 					return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
463 						@Override
464 						public Boolean run() {
465 							return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
466 									!factoryBean.isSingleton());
467 						}
468 					}, getAccessControlContext());
469 				}
470 				else {
471 					return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
472 							!factoryBean.isSingleton());
473 				}
474 			}
475 			else {
476 				return false;
477 			}
478 		}
479 	}
480 
481 	@Override
482 	public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
483 		String beanName = transformedBeanName(name);
484 		Class<?> typeToMatch = (targetType != null ? targetType : Object.class);
485 
486 		// Check manually registered singletons.
487 		Object beanInstance = getSingleton(beanName, false);
488 		if (beanInstance != null) {
489 			if (beanInstance instanceof FactoryBean) {
490 				if (!BeanFactoryUtils.isFactoryDereference(name)) {
491 					Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
492 					return (type != null && ClassUtils.isAssignable(typeToMatch, type));
493 				}
494 				else {
495 					return ClassUtils.isAssignableValue(typeToMatch, beanInstance);
496 				}
497 			}
498 			else {
499 				return !BeanFactoryUtils.isFactoryDereference(name) &&
500 						ClassUtils.isAssignableValue(typeToMatch, beanInstance);
501 			}
502 		}
503 		else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
504 			// null instance registered
505 			return false;
506 		}
507 
508 		else {
509 			// No singleton instance found -> check bean definition.
510 			BeanFactory parentBeanFactory = getParentBeanFactory();
511 			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
512 				// No bean definition found in this factory -> delegate to parent.
513 				return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
514 			}
515 
516 			// Retrieve corresponding bean definition.
517 			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
518 
519 			Class<?>[] typesToMatch = (FactoryBean.class.equals(typeToMatch) ?
520 					new Class<?>[] {typeToMatch} : new Class<?>[] {FactoryBean.class, typeToMatch});
521 
522 			// Check decorated bean definition, if any: We assume it'll be easier
523 			// to determine the decorated bean's type than the proxy's type.
524 			BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
525 			if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
526 				RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
527 				Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
528 				if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
529 					return typeToMatch.isAssignableFrom(targetClass);
530 				}
531 			}
532 
533 			Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
534 			if (beanType == null) {
535 				return false;
536 			}
537 
538 			// Check bean class whether we're dealing with a FactoryBean.
539 			if (FactoryBean.class.isAssignableFrom(beanType)) {
540 				if (!BeanFactoryUtils.isFactoryDereference(name)) {
541 					// If it's a FactoryBean, we want to look at what it creates, not the factory class.
542 					beanType = getTypeForFactoryBean(beanName, mbd);
543 					if (beanType == null) {
544 						return false;
545 					}
546 				}
547 			}
548 			else if (BeanFactoryUtils.isFactoryDereference(name)) {
549 				// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
550 				// type but we nevertheless are being asked to dereference a FactoryBean...
551 				// Let's check the original bean class and proceed with it if it is a FactoryBean.
552 				beanType = predictBeanType(beanName, mbd, FactoryBean.class);
553 				if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) {
554 					return false;
555 				}
556 			}
557 
558 			return typeToMatch.isAssignableFrom(beanType);
559 		}
560 	}
561 
562 	@Override
563 	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
564 		String beanName = transformedBeanName(name);
565 
566 		// Check manually registered singletons.
567 		Object beanInstance = getSingleton(beanName, false);
568 		if (beanInstance != null) {
569 			if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
570 				return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
571 			}
572 			else {
573 				return beanInstance.getClass();
574 			}
575 		}
576 		else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
577 			// null instance registered
578 			return null;
579 		}
580 
581 		else {
582 			// No singleton instance found -> check bean definition.
583 			BeanFactory parentBeanFactory = getParentBeanFactory();
584 			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
585 				// No bean definition found in this factory -> delegate to parent.
586 				return parentBeanFactory.getType(originalBeanName(name));
587 			}
588 
589 			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
590 
591 			// Check decorated bean definition, if any: We assume it'll be easier
592 			// to determine the decorated bean's type than the proxy's type.
593 			BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
594 			if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
595 				RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
596 				Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
597 				if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
598 					return targetClass;
599 				}
600 			}
601 
602 			Class<?> beanClass = predictBeanType(beanName, mbd);
603 
604 			// Check bean class whether we're dealing with a FactoryBean.
605 			if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
606 				if (!BeanFactoryUtils.isFactoryDereference(name)) {
607 					// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
608 					return getTypeForFactoryBean(beanName, mbd);
609 				}
610 				else {
611 					return beanClass;
612 				}
613 			}
614 			else {
615 				return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
616 			}
617 		}
618 	}
619 
620 	@Override
621 	public String[] getAliases(String name) {
622 		String beanName = transformedBeanName(name);
623 		List<String> aliases = new ArrayList<String>();
624 		boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);
625 		String fullBeanName = beanName;
626 		if (factoryPrefix) {
627 			fullBeanName = FACTORY_BEAN_PREFIX + beanName;
628 		}
629 		if (!fullBeanName.equals(name)) {
630 			aliases.add(fullBeanName);
631 		}
632 		String[] retrievedAliases = super.getAliases(beanName);
633 		for (String retrievedAlias : retrievedAliases) {
634 			String alias = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + retrievedAlias;
635 			if (!alias.equals(name)) {
636 				aliases.add(alias);
637 			}
638 		}
639 		if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
640 			BeanFactory parentBeanFactory = getParentBeanFactory();
641 			if (parentBeanFactory != null) {
642 				aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName)));
643 			}
644 		}
645 		return StringUtils.toStringArray(aliases);
646 	}
647 
648 
649 	//---------------------------------------------------------------------
650 	// Implementation of HierarchicalBeanFactory interface
651 	//---------------------------------------------------------------------
652 
653 	@Override
654 	public BeanFactory getParentBeanFactory() {
655 		return this.parentBeanFactory;
656 	}
657 
658 	@Override
659 	public boolean containsLocalBean(String name) {
660 		String beanName = transformedBeanName(name);
661 		return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
662 				(!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName)));
663 	}
664 
665 
666 	//---------------------------------------------------------------------
667 	// Implementation of ConfigurableBeanFactory interface
668 	//---------------------------------------------------------------------
669 
670 	@Override
671 	public void setParentBeanFactory(BeanFactory parentBeanFactory) {
672 		if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
673 			throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
674 		}
675 		this.parentBeanFactory = parentBeanFactory;
676 	}
677 
678 	@Override
679 	public void setBeanClassLoader(ClassLoader beanClassLoader) {
680 		this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader());
681 	}
682 
683 	@Override
684 	public ClassLoader getBeanClassLoader() {
685 		return this.beanClassLoader;
686 	}
687 
688 	@Override
689 	public void setTempClassLoader(ClassLoader tempClassLoader) {
690 		this.tempClassLoader = tempClassLoader;
691 	}
692 
693 	@Override
694 	public ClassLoader getTempClassLoader() {
695 		return this.tempClassLoader;
696 	}
697 
698 	@Override
699 	public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
700 		this.cacheBeanMetadata = cacheBeanMetadata;
701 	}
702 
703 	@Override
704 	public boolean isCacheBeanMetadata() {
705 		return this.cacheBeanMetadata;
706 	}
707 
708 	@Override
709 	public void setBeanExpressionResolver(BeanExpressionResolver resolver) {
710 		this.beanExpressionResolver = resolver;
711 	}
712 
713 	@Override
714 	public BeanExpressionResolver getBeanExpressionResolver() {
715 		return this.beanExpressionResolver;
716 	}
717 
718 	@Override
719 	public void setConversionService(ConversionService conversionService) {
720 		this.conversionService = conversionService;
721 	}
722 
723 	@Override
724 	public ConversionService getConversionService() {
725 		return this.conversionService;
726 	}
727 
728 	@Override
729 	public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
730 		Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
731 		this.propertyEditorRegistrars.add(registrar);
732 	}
733 
734 	/**
735 	 * Return the set of PropertyEditorRegistrars.
736 	 */
737 	public Set<PropertyEditorRegistrar> getPropertyEditorRegistrars() {
738 		return this.propertyEditorRegistrars;
739 	}
740 
741 	@Override
742 	public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
743 		Assert.notNull(requiredType, "Required type must not be null");
744 		Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
745 		this.customEditors.put(requiredType, propertyEditorClass);
746 	}
747 
748 	@Override
749 	public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) {
750 		registerCustomEditors(registry);
751 	}
752 
753 	/**
754 	 * Return the map of custom editors, with Classes as keys and PropertyEditor classes as values.
755 	 */
756 	public Map<Class<?>, Class<? extends PropertyEditor>> getCustomEditors() {
757 		return this.customEditors;
758 	}
759 
760 	@Override
761 	public void setTypeConverter(TypeConverter typeConverter) {
762 		this.typeConverter = typeConverter;
763 	}
764 
765 	/**
766 	 * Return the custom TypeConverter to use, if any.
767 	 * @return the custom TypeConverter, or {@code null} if none specified
768 	 */
769 	protected TypeConverter getCustomTypeConverter() {
770 		return this.typeConverter;
771 	}
772 
773 	@Override
774 	public TypeConverter getTypeConverter() {
775 		TypeConverter customConverter = getCustomTypeConverter();
776 		if (customConverter != null) {
777 			return customConverter;
778 		}
779 		else {
780 			// Build default TypeConverter, registering custom editors.
781 			SimpleTypeConverter typeConverter = new SimpleTypeConverter();
782 			typeConverter.setConversionService(getConversionService());
783 			registerCustomEditors(typeConverter);
784 			return typeConverter;
785 		}
786 	}
787 
788 	@Override
789 	public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
790 		Assert.notNull(valueResolver, "StringValueResolver must not be null");
791 		this.embeddedValueResolvers.add(valueResolver);
792 	}
793 
794 	@Override
795 	public String resolveEmbeddedValue(String value) {
796 		String result = value;
797 		for (StringValueResolver resolver : this.embeddedValueResolvers) {
798 			if (result == null) {
799 				return null;
800 			}
801 			result = resolver.resolveStringValue(result);
802 		}
803 		return result;
804 	}
805 
806 	@Override
807 	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
808 		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
809 		this.beanPostProcessors.remove(beanPostProcessor);
810 		this.beanPostProcessors.add(beanPostProcessor);
811 		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
812 			this.hasInstantiationAwareBeanPostProcessors = true;
813 		}
814 		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
815 			this.hasDestructionAwareBeanPostProcessors = true;
816 		}
817 	}
818 
819 	@Override
820 	public int getBeanPostProcessorCount() {
821 		return this.beanPostProcessors.size();
822 	}
823 
824 	/**
825 	 * Return the list of BeanPostProcessors that will get applied
826 	 * to beans created with this factory.
827 	 */
828 	public List<BeanPostProcessor> getBeanPostProcessors() {
829 		return this.beanPostProcessors;
830 	}
831 
832 	/**
833 	 * Return whether this factory holds a InstantiationAwareBeanPostProcessor
834 	 * that will get applied to singleton beans on shutdown.
835 	 * @see #addBeanPostProcessor
836 	 * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
837 	 */
838 	protected boolean hasInstantiationAwareBeanPostProcessors() {
839 		return this.hasInstantiationAwareBeanPostProcessors;
840 	}
841 
842 	/**
843 	 * Return whether this factory holds a DestructionAwareBeanPostProcessor
844 	 * that will get applied to singleton beans on shutdown.
845 	 * @see #addBeanPostProcessor
846 	 * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
847 	 */
848 	protected boolean hasDestructionAwareBeanPostProcessors() {
849 		return this.hasDestructionAwareBeanPostProcessors;
850 	}
851 
852 	@Override
853 	public void registerScope(String scopeName, Scope scope) {
854 		Assert.notNull(scopeName, "Scope identifier must not be null");
855 		Assert.notNull(scope, "Scope must not be null");
856 		if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) {
857 			throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'");
858 		}
859 		Scope previous = this.scopes.put(scopeName, scope);
860 		if (previous != null && previous != scope) {
861 			if (logger.isInfoEnabled()) {
862 				logger.info("Replacing scope '" + scopeName + "' from [" + previous + "] to [" + scope + "]");
863 			}
864 		}
865 		else {
866 			if (logger.isDebugEnabled()) {
867 				logger.debug("Registering scope '" + scopeName + "' with implementation [" + scope + "]");
868 			}
869 		}
870 	}
871 
872 	@Override
873 	public String[] getRegisteredScopeNames() {
874 		return StringUtils.toStringArray(this.scopes.keySet());
875 	}
876 
877 	@Override
878 	public Scope getRegisteredScope(String scopeName) {
879 		Assert.notNull(scopeName, "Scope identifier must not be null");
880 		return this.scopes.get(scopeName);
881 	}
882 
883 	/**
884 	 * Set the security context provider for this bean factory. If a security manager
885 	 * is set, interaction with the user code will be executed using the privileged
886 	 * of the provided security context.
887 	 */
888 	public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
889 		this.securityContextProvider = securityProvider;
890 	}
891 
892 	/**
893 	 * Delegate the creation of the access control context to the
894 	 * {@link #setSecurityContextProvider SecurityContextProvider}.
895 	 */
896 	@Override
897 	public AccessControlContext getAccessControlContext() {
898 		return (this.securityContextProvider != null ?
899 				this.securityContextProvider.getAccessControlContext() :
900 				AccessController.getContext());
901 	}
902 
903 	@Override
904 	public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
905 		Assert.notNull(otherFactory, "BeanFactory must not be null");
906 		setBeanClassLoader(otherFactory.getBeanClassLoader());
907 		setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
908 		setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
909 		if (otherFactory instanceof AbstractBeanFactory) {
910 			AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
911 			this.customEditors.putAll(otherAbstractFactory.customEditors);
912 			this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
913 			this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
914 			this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
915 					otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
916 			this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
917 					otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
918 			this.scopes.putAll(otherAbstractFactory.scopes);
919 			this.securityContextProvider = otherAbstractFactory.securityContextProvider;
920 		}
921 		else {
922 			setTypeConverter(otherFactory.getTypeConverter());
923 		}
924 	}
925 
926 	/**
927 	 * Return a 'merged' BeanDefinition for the given bean name,
928 	 * merging a child bean definition with its parent if necessary.
929 	 * <p>This {@code getMergedBeanDefinition} considers bean definition
930 	 * in ancestors as well.
931 	 * @param name the name of the bean to retrieve the merged definition for
932 	 * (may be an alias)
933 	 * @return a (potentially merged) RootBeanDefinition for the given bean
934 	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
935 	 * @throws BeanDefinitionStoreException in case of an invalid bean definition
936 	 */
937 	@Override
938 	public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
939 		String beanName = transformedBeanName(name);
940 
941 		// Efficiently check whether bean definition exists in this factory.
942 		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
943 			return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
944 		}
945 		// Resolve merged bean definition locally.
946 		return getMergedLocalBeanDefinition(beanName);
947 	}
948 
949 	@Override
950 	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
951 		String beanName = transformedBeanName(name);
952 
953 		Object beanInstance = getSingleton(beanName, false);
954 		if (beanInstance != null) {
955 			return (beanInstance instanceof FactoryBean);
956 		}
957 		else if (containsSingleton(beanName)) {
958 			// null instance registered
959 			return false;
960 		}
961 
962 		// No singleton instance found -> check bean definition.
963 		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
964 			// No bean definition found in this factory -> delegate to parent.
965 			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
966 		}
967 
968 		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
969 	}
970 
971 	@Override
972 	public boolean isActuallyInCreation(String beanName) {
973 		return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName));
974 	}
975 
976 	/**
977 	 * Return whether the specified prototype bean is currently in creation
978 	 * (within the current thread).
979 	 * @param beanName the name of the bean
980 	 */
981 	protected boolean isPrototypeCurrentlyInCreation(String beanName) {
982 		Object curVal = this.prototypesCurrentlyInCreation.get();
983 		return (curVal != null &&
984 				(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
985 	}
986 
987 	/**
988 	 * Callback before prototype creation.
989 	 * <p>The default implementation register the prototype as currently in creation.
990 	 * @param beanName the name of the prototype about to be created
991 	 * @see #isPrototypeCurrentlyInCreation
992 	 */
993 	@SuppressWarnings("unchecked")
994 	protected void beforePrototypeCreation(String beanName) {
995 		Object curVal = this.prototypesCurrentlyInCreation.get();
996 		if (curVal == null) {
997 			this.prototypesCurrentlyInCreation.set(beanName);
998 		}
999 		else if (curVal instanceof String) {
1000 			Set<String> beanNameSet = new HashSet<String>(2);
1001 			beanNameSet.add((String) curVal);
1002 			beanNameSet.add(beanName);
1003 			this.prototypesCurrentlyInCreation.set(beanNameSet);
1004 		}
1005 		else {
1006 			Set<String> beanNameSet = (Set<String>) curVal;
1007 			beanNameSet.add(beanName);
1008 		}
1009 	}
1010 
1011 	/**
1012 	 * Callback after prototype creation.
1013 	 * <p>The default implementation marks the prototype as not in creation anymore.
1014 	 * @param beanName the name of the prototype that has been created
1015 	 * @see #isPrototypeCurrentlyInCreation
1016 	 */
1017 	@SuppressWarnings("unchecked")
1018 	protected void afterPrototypeCreation(String beanName) {
1019 		Object curVal = this.prototypesCurrentlyInCreation.get();
1020 		if (curVal instanceof String) {
1021 			this.prototypesCurrentlyInCreation.remove();
1022 		}
1023 		else if (curVal instanceof Set) {
1024 			Set<String> beanNameSet = (Set<String>) curVal;
1025 			beanNameSet.remove(beanName);
1026 			if (beanNameSet.isEmpty()) {
1027 				this.prototypesCurrentlyInCreation.remove();
1028 			}
1029 		}
1030 	}
1031 
1032 	@Override
1033 	public void destroyBean(String beanName, Object beanInstance) {
1034 		destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
1035 	}
1036 
1037 	/**
1038 	 * Destroy the given bean instance (usually a prototype instance
1039 	 * obtained from this factory) according to the given bean definition.
1040 	 * @param beanName the name of the bean definition
1041 	 * @param beanInstance the bean instance to destroy
1042 	 * @param mbd the merged bean definition
1043 	 */
1044 	protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
1045 		new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
1046 	}
1047 
1048 	@Override
1049 	public void destroyScopedBean(String beanName) {
1050 		RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
1051 		if (mbd.isSingleton() || mbd.isPrototype()) {
1052 			throw new IllegalArgumentException(
1053 					"Bean name '" + beanName + "' does not correspond to an object in a mutable scope");
1054 		}
1055 		String scopeName = mbd.getScope();
1056 		Scope scope = this.scopes.get(scopeName);
1057 		if (scope == null) {
1058 			throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'");
1059 		}
1060 		Object bean = scope.remove(beanName);
1061 		if (bean != null) {
1062 			destroyBean(beanName, bean, mbd);
1063 		}
1064 	}
1065 
1066 
1067 	//---------------------------------------------------------------------
1068 	// Implementation methods
1069 	//---------------------------------------------------------------------
1070 
1071 	/**
1072 	 * Return the bean name, stripping out the factory dereference prefix if necessary,
1073 	 * and resolving aliases to canonical names.
1074 	 * @param name the user-specified name
1075 	 * @return the transformed bean name
1076 	 */
1077 	protected String transformedBeanName(String name) {
1078 		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
1079 	}
1080 
1081 	/**
1082 	 * Determine the original bean name, resolving locally defined aliases to canonical names.
1083 	 * @param name the user-specified name
1084 	 * @return the original bean name
1085 	 */
1086 	protected String originalBeanName(String name) {
1087 		String beanName = transformedBeanName(name);
1088 		if (name.startsWith(FACTORY_BEAN_PREFIX)) {
1089 			beanName = FACTORY_BEAN_PREFIX + beanName;
1090 		}
1091 		return beanName;
1092 	}
1093 
1094 	/**
1095 	 * Initialize the given BeanWrapper with the custom editors registered
1096 	 * with this factory. To be called for BeanWrappers that will create
1097 	 * and populate bean instances.
1098 	 * <p>The default implementation delegates to {@link #registerCustomEditors}.
1099 	 * Can be overridden in subclasses.
1100 	 * @param bw the BeanWrapper to initialize
1101 	 */
1102 	protected void initBeanWrapper(BeanWrapper bw) {
1103 		bw.setConversionService(getConversionService());
1104 		registerCustomEditors(bw);
1105 	}
1106 
1107 	/**
1108 	 * Initialize the given PropertyEditorRegistry with the custom editors
1109 	 * that have been registered with this BeanFactory.
1110 	 * <p>To be called for BeanWrappers that will create and populate bean
1111 	 * instances, and for SimpleTypeConverter used for constructor argument
1112 	 * and factory method type conversion.
1113 	 * @param registry the PropertyEditorRegistry to initialize
1114 	 */
1115 	protected void registerCustomEditors(PropertyEditorRegistry registry) {
1116 		PropertyEditorRegistrySupport registrySupport =
1117 				(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
1118 		if (registrySupport != null) {
1119 			registrySupport.useConfigValueEditors();
1120 		}
1121 		if (!this.propertyEditorRegistrars.isEmpty()) {
1122 			for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
1123 				try {
1124 					registrar.registerCustomEditors(registry);
1125 				}
1126 				catch (BeanCreationException ex) {
1127 					Throwable rootCause = ex.getMostSpecificCause();
1128 					if (rootCause instanceof BeanCurrentlyInCreationException) {
1129 						BeanCreationException bce = (BeanCreationException) rootCause;
1130 						if (isCurrentlyInCreation(bce.getBeanName())) {
1131 							if (logger.isDebugEnabled()) {
1132 								logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
1133 										"] failed because it tried to obtain currently created bean '" +
1134 										ex.getBeanName() + "': " + ex.getMessage());
1135 							}
1136 							onSuppressedException(ex);
1137 							continue;
1138 						}
1139 					}
1140 					throw ex;
1141 				}
1142 			}
1143 		}
1144 		if (!this.customEditors.isEmpty()) {
1145 			for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {
1146 				Class<?> requiredType = entry.getKey();
1147 				Class<? extends PropertyEditor> editorClass = entry.getValue();
1148 				registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));
1149 			}
1150 		}
1151 	}
1152 
1153 
1154 	/**
1155 	 * Return a merged RootBeanDefinition, traversing the parent bean definition
1156 	 * if the specified bean corresponds to a child bean definition.
1157 	 * @param beanName the name of the bean to retrieve the merged definition for
1158 	 * @return a (potentially merged) RootBeanDefinition for the given bean
1159 	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
1160 	 * @throws BeanDefinitionStoreException in case of an invalid bean definition
1161 	 */
1162 	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
1163 		// Quick check on the concurrent map first, with minimal locking.
1164 		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
1165 		if (mbd != null) {
1166 			return mbd;
1167 		}
1168 		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
1169 	}
1170 
1171 	/**
1172 	 * Return a RootBeanDefinition for the given top-level bean, by merging with
1173 	 * the parent if the given bean's definition is a child bean definition.
1174 	 * @param beanName the name of the bean definition
1175 	 * @param bd the original bean definition (Root/ChildBeanDefinition)
1176 	 * @return a (potentially merged) RootBeanDefinition for the given bean
1177 	 * @throws BeanDefinitionStoreException in case of an invalid bean definition
1178 	 */
1179 	protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
1180 			throws BeanDefinitionStoreException {
1181 
1182 		return getMergedBeanDefinition(beanName, bd, null);
1183 	}
1184 
1185 	/**
1186 	 * Return a RootBeanDefinition for the given bean, by merging with the
1187 	 * parent if the given bean's definition is a child bean definition.
1188 	 * @param beanName the name of the bean definition
1189 	 * @param bd the original bean definition (Root/ChildBeanDefinition)
1190 	 * @param containingBd the containing bean definition in case of inner bean,
1191 	 * or {@code null} in case of a top-level bean
1192 	 * @return a (potentially merged) RootBeanDefinition for the given bean
1193 	 * @throws BeanDefinitionStoreException in case of an invalid bean definition
1194 	 */
1195 	protected RootBeanDefinition getMergedBeanDefinition(
1196 			String beanName, BeanDefinition bd, BeanDefinition containingBd)
1197 			throws BeanDefinitionStoreException {
1198 
1199 		synchronized (this.mergedBeanDefinitions) {
1200 			RootBeanDefinition mbd = null;
1201 
1202 			// Check with full lock now in order to enforce the same merged instance.
1203 			if (containingBd == null) {
1204 				mbd = this.mergedBeanDefinitions.get(beanName);
1205 			}
1206 
1207 			if (mbd == null) {
1208 				if (bd.getParentName() == null) {
1209 					// Use copy of given root bean definition.
1210 					if (bd instanceof RootBeanDefinition) {
1211 						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
1212 					}
1213 					else {
1214 						mbd = new RootBeanDefinition(bd);
1215 					}
1216 				}
1217 				else {
1218 					// Child bean definition: needs to be merged with parent.
1219 					BeanDefinition pbd;
1220 					try {
1221 						String parentBeanName = transformedBeanName(bd.getParentName());
1222 						if (!beanName.equals(parentBeanName)) {
1223 							pbd = getMergedBeanDefinition(parentBeanName);
1224 						}
1225 						else {
1226 							if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
1227 								pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
1228 							}
1229 							else {
1230 								throw new NoSuchBeanDefinitionException(bd.getParentName(),
1231 										"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
1232 										"': cannot be resolved without an AbstractBeanFactory parent");
1233 							}
1234 						}
1235 					}
1236 					catch (NoSuchBeanDefinitionException ex) {
1237 						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
1238 								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
1239 					}
1240 					// Deep copy with overridden values.
1241 					mbd = new RootBeanDefinition(pbd);
1242 					mbd.overrideFrom(bd);
1243 				}
1244 
1245 				// Set default singleton scope, if not configured before.
1246 				if (!StringUtils.hasLength(mbd.getScope())) {
1247 					mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
1248 				}
1249 
1250 				// A bean contained in a non-singleton bean cannot be a singleton itself.
1251 				// Let's correct this on the fly here, since this might be the result of
1252 				// parent-child merging for the outer bean, in which case the original inner bean
1253 				// definition will not have inherited the merged outer bean's singleton status.
1254 				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
1255 					mbd.setScope(containingBd.getScope());
1256 				}
1257 
1258 				// Only cache the merged bean definition if we're already about to create an
1259 				// instance of the bean, or at least have already created an instance before.
1260 				if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
1261 					this.mergedBeanDefinitions.put(beanName, mbd);
1262 				}
1263 			}
1264 
1265 			return mbd;
1266 		}
1267 	}
1268 
1269 	/**
1270 	 * Check the given merged bean definition,
1271 	 * potentially throwing validation exceptions.
1272 	 * @param mbd the merged bean definition to check
1273 	 * @param beanName the name of the bean
1274 	 * @param args the arguments for bean creation, if any
1275 	 * @throws BeanDefinitionStoreException in case of validation failure
1276 	 */
1277 	protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
1278 			throws BeanDefinitionStoreException {
1279 
1280 		if (mbd.isAbstract()) {
1281 			throw new BeanIsAbstractException(beanName);
1282 		}
1283 	}
1284 
1285 	/**
1286 	 * Remove the merged bean definition for the specified bean,
1287 	 * recreating it on next access.
1288 	 * @param beanName the bean name to clear the merged definition for
1289 	 */
1290 	protected void clearMergedBeanDefinition(String beanName) {
1291 		this.mergedBeanDefinitions.remove(beanName);
1292 	}
1293 
1294 	/**
1295 	 * Resolve the bean class for the specified bean definition,
1296 	 * resolving a bean class name into a Class reference (if necessary)
1297 	 * and storing the resolved Class in the bean definition for further use.
1298 	 * @param mbd the merged bean definition to determine the class for
1299 	 * @param beanName the name of the bean (for error handling purposes)
1300 	 * @param typesToMatch the types to match in case of internal type matching purposes
1301 	 * (also signals that the returned {@code Class} will never be exposed to application code)
1302 	 * @return the resolved bean class (or {@code null} if none)
1303 	 * @throws CannotLoadBeanClassException if we failed to load the class
1304 	 */
1305 	protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
1306 			throws CannotLoadBeanClassException {
1307 		try {
1308 			if (mbd.hasBeanClass()) {
1309 				return mbd.getBeanClass();
1310 			}
1311 			if (System.getSecurityManager() != null) {
1312 				return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
1313 					@Override
1314 					public Class<?> run() throws Exception {
1315 						return doResolveBeanClass(mbd, typesToMatch);
1316 					}
1317 				}, getAccessControlContext());
1318 			}
1319 			else {
1320 				return doResolveBeanClass(mbd, typesToMatch);
1321 			}
1322 		}
1323 		catch (PrivilegedActionException pae) {
1324 			ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
1325 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
1326 		}
1327 		catch (ClassNotFoundException ex) {
1328 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
1329 		}
1330 		catch (LinkageError err) {
1331 			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
1332 		}
1333 	}
1334 
1335 	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
1336 		if (!ObjectUtils.isEmpty(typesToMatch)) {
1337 			ClassLoader tempClassLoader = getTempClassLoader();
1338 			if (tempClassLoader != null) {
1339 				if (tempClassLoader instanceof DecoratingClassLoader) {
1340 					DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
1341 					for (Class<?> typeToMatch : typesToMatch) {
1342 						dcl.excludeClass(typeToMatch.getName());
1343 					}
1344 				}
1345 				String className = mbd.getBeanClassName();
1346 				return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
1347 			}
1348 		}
1349 		return mbd.resolveBeanClass(getBeanClassLoader());
1350 	}
1351 
1352 	/**
1353 	 * Evaluate the given String as contained in a bean definition,
1354 	 * potentially resolving it as an expression.
1355 	 * @param value the value to check
1356 	 * @param beanDefinition the bean definition that the value comes from
1357 	 * @return the resolved value
1358 	 * @see #setBeanExpressionResolver
1359 	 */
1360 	protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
1361 		if (this.beanExpressionResolver == null) {
1362 			return value;
1363 		}
1364 		Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
1365 		return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
1366 	}
1367 
1368 
1369 	/**
1370 	 * Predict the eventual bean type (of the processed bean instance) for the
1371 	 * specified bean. Called by {@link #getType} and {@link #isTypeMatch}.
1372 	 * Does not need to handle FactoryBeans specifically, since it is only
1373 	 * supposed to operate on the raw bean type.
1374 	 * <p>This implementation is simplistic in that it is not able to
1375 	 * handle factory methods and InstantiationAwareBeanPostProcessors.
1376 	 * It only predicts the bean type correctly for a standard bean.
1377 	 * To be overridden in subclasses, applying more sophisticated type detection.
1378 	 * @param beanName the name of the bean
1379 	 * @param mbd the merged bean definition to determine the type for
1380 	 * @param typesToMatch the types to match in case of internal type matching purposes
1381 	 * (also signals that the returned {@code Class} will never be exposed to application code)
1382 	 * @return the type of the bean, or {@code null} if not predictable
1383 	 */
1384 	protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
1385 		if (mbd.getFactoryMethodName() != null) {
1386 			return null;
1387 		}
1388 		return resolveBeanClass(mbd, beanName, typesToMatch);
1389 	}
1390 
1391 	/**
1392 	 * Check whether the given bean is defined as a {@link FactoryBean}.
1393 	 * @param beanName the name of the bean
1394 	 * @param mbd the corresponding bean definition
1395 	 */
1396 	protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
1397 		Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
1398 		return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
1399 	}
1400 
1401 	/**
1402 	 * Determine the bean type for the given FactoryBean definition, as far as possible.
1403 	 * Only called if there is no singleton instance registered for the target bean already.
1404 	 * <p>The default implementation creates the FactoryBean via {@code getBean}
1405 	 * to call its {@code getObjectType} method. Subclasses are encouraged to optimize
1406 	 * this, typically by just instantiating the FactoryBean but not populating it yet,
1407 	 * trying whether its {@code getObjectType} method already returns a type.
1408 	 * If no type found, a full FactoryBean creation as performed by this implementation
1409 	 * should be used as fallback.
1410 	 * @param beanName the name of the bean
1411 	 * @param mbd the merged bean definition for the bean
1412 	 * @return the type for the bean if determinable, or {@code null} else
1413 	 * @see org.springframework.beans.factory.FactoryBean#getObjectType()
1414 	 * @see #getBean(String)
1415 	 */
1416 	protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
1417 		if (!mbd.isSingleton()) {
1418 			return null;
1419 		}
1420 		try {
1421 			FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
1422 			return getTypeForFactoryBean(factoryBean);
1423 		}
1424 		catch (BeanCreationException ex) {
1425 			// Can only happen when getting a FactoryBean.
1426 			if (logger.isWarnEnabled()) {
1427 				logger.warn("Bean creation exception on FactoryBean type check: " + ex);
1428 			}
1429 			onSuppressedException(ex);
1430 			return null;
1431 		}
1432 	}
1433 
1434 	/**
1435 	 * Mark the specified bean as already created (or about to be created).
1436 	 * <p>This allows the bean factory to optimize its caching for repeated
1437 	 * creation of the specified bean.
1438 	 * @param beanName the name of the bean
1439 	 */
1440 	protected void markBeanAsCreated(String beanName) {
1441 		if (!this.alreadyCreated.contains(beanName)) {
1442 			this.alreadyCreated.add(beanName);
1443 		}
1444 	}
1445 
1446 	/**
1447 	 * Perform appropriate cleanup of cached metadata after bean creation failed.
1448 	 * @param beanName the name of the bean
1449 	 */
1450 	protected void cleanupAfterBeanCreationFailure(String beanName) {
1451 		this.alreadyCreated.remove(beanName);
1452 	}
1453 
1454 	/**
1455 	 * Determine whether the specified bean is eligible for having
1456 	 * its bean definition metadata cached.
1457 	 * @param beanName the name of the bean
1458 	 * @return {@code true} if the bean's metadata may be cached
1459 	 * at this point already
1460 	 */
1461 	protected boolean isBeanEligibleForMetadataCaching(String beanName) {
1462 		return this.alreadyCreated.contains(beanName);
1463 	}
1464 
1465 	/**
1466 	 * Remove the singleton instance (if any) for the given bean name,
1467 	 * but only if it hasn't been used for other purposes than type checking.
1468 	 * @param beanName the name of the bean
1469 	 * @return {@code true} if actually removed, {@code false} otherwise
1470 	 */
1471 	protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
1472 		if (!this.alreadyCreated.contains(beanName)) {
1473 			removeSingleton(beanName);
1474 			return true;
1475 		}
1476 		else {
1477 			return false;
1478 		}
1479 	}
1480 
1481 	/**
1482 	 * Get the object for the given bean instance, either the bean
1483 	 * instance itself or its created object in case of a FactoryBean.
1484 	 * @param beanInstance the shared bean instance
1485 	 * @param name name that may include factory dereference prefix
1486 	 * @param beanName the canonical bean name
1487 	 * @param mbd the merged bean definition
1488 	 * @return the object to expose for the bean
1489 	 */
1490 	protected Object getObjectForBeanInstance(
1491 			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
1492 
1493 		// Don't let calling code try to dereference the factory if the bean isn't a factory.
1494 		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
1495 			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
1496 		}
1497 
1498 		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
1499 		// If it's a FactoryBean, we use it to create a bean instance, unless the
1500 		// caller actually wants a reference to the factory.
1501 		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
1502 			return beanInstance;
1503 		}
1504 
1505 		Object object = null;
1506 		if (mbd == null) {
1507 			object = getCachedObjectForFactoryBean(beanName);
1508 		}
1509 		if (object == null) {
1510 			// Return bean instance from factory.
1511 			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
1512 			// Caches object obtained from FactoryBean if it is a singleton.
1513 			if (mbd == null && containsBeanDefinition(beanName)) {
1514 				mbd = getMergedLocalBeanDefinition(beanName);
1515 			}
1516 			boolean synthetic = (mbd != null && mbd.isSynthetic());
1517 			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
1518 		}
1519 		return object;
1520 	}
1521 
1522 	/**
1523 	 * Determine whether the given bean name is already in use within this factory,
1524 	 * i.e. whether there is a local bean or alias registered under this name or
1525 	 * an inner bean created with this name.
1526 	 * @param beanName the name to check
1527 	 */
1528 	public boolean isBeanNameInUse(String beanName) {
1529 		return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName);
1530 	}
1531 
1532 	/**
1533 	 * Determine whether the given bean requires destruction on shutdown.
1534 	 * <p>The default implementation checks the DisposableBean interface as well as
1535 	 * a specified destroy method and registered DestructionAwareBeanPostProcessors.
1536 	 * @param bean the bean instance to check
1537 	 * @param mbd the corresponding bean definition
1538 	 * @see org.springframework.beans.factory.DisposableBean
1539 	 * @see AbstractBeanDefinition#getDestroyMethodName()
1540 	 * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
1541 	 */
1542 	protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
1543 		return (bean != null &&
1544 				(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || hasDestructionAwareBeanPostProcessors()));
1545 	}
1546 
1547 	/**
1548 	 * Add the given bean to the list of disposable beans in this factory,
1549 	 * registering its DisposableBean interface and/or the given destroy method
1550 	 * to be called on factory shutdown (if applicable). Only applies to singletons.
1551 	 * @param beanName the name of the bean
1552 	 * @param bean the bean instance
1553 	 * @param mbd the bean definition for the bean
1554 	 * @see RootBeanDefinition#isSingleton
1555 	 * @see RootBeanDefinition#getDependsOn
1556 	 * @see #registerDisposableBean
1557 	 * @see #registerDependentBean
1558 	 */
1559 	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
1560 		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
1561 		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
1562 			if (mbd.isSingleton()) {
1563 				// Register a DisposableBean implementation that performs all destruction
1564 				// work for the given bean: DestructionAwareBeanPostProcessors,
1565 				// DisposableBean interface, custom destroy method.
1566 				registerDisposableBean(beanName,
1567 						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1568 			}
1569 			else {
1570 				// A bean with a custom scope...
1571 				Scope scope = this.scopes.get(mbd.getScope());
1572 				if (scope == null) {
1573 					throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
1574 				}
1575 				scope.registerDestructionCallback(beanName,
1576 						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1577 			}
1578 		}
1579 	}
1580 
1581 
1582 	//---------------------------------------------------------------------
1583 	// Abstract methods to be implemented by subclasses
1584 	//---------------------------------------------------------------------
1585 
1586 	/**
1587 	 * Check if this bean factory contains a bean definition with the given name.
1588 	 * Does not consider any hierarchy this factory may participate in.
1589 	 * Invoked by {@code containsBean} when no cached singleton instance is found.
1590 	 * <p>Depending on the nature of the concrete bean factory implementation,
1591 	 * this operation might be expensive (for example, because of directory lookups
1592 	 * in external registries). However, for listable bean factories, this usually
1593 	 * just amounts to a local hash lookup: The operation is therefore part of the
1594 	 * public interface there. The same implementation can serve for both this
1595 	 * template method and the public interface method in that case.
1596 	 * @param beanName the name of the bean to look for
1597 	 * @return if this bean factory contains a bean definition with the given name
1598 	 * @see #containsBean
1599 	 * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
1600 	 */
1601 	protected abstract boolean containsBeanDefinition(String beanName);
1602 
1603 	/**
1604 	 * Return the bean definition for the given bean name.
1605 	 * Subclasses should normally implement caching, as this method is invoked
1606 	 * by this class every time bean definition metadata is needed.
1607 	 * <p>Depending on the nature of the concrete bean factory implementation,
1608 	 * this operation might be expensive (for example, because of directory lookups
1609 	 * in external registries). However, for listable bean factories, this usually
1610 	 * just amounts to a local hash lookup: The operation is therefore part of the
1611 	 * public interface there. The same implementation can serve for both this
1612 	 * template method and the public interface method in that case.
1613 	 * @param beanName the name of the bean to find a definition for
1614 	 * @return the BeanDefinition for this prototype name (never {@code null})
1615 	 * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
1616 	 * if the bean definition cannot be resolved
1617 	 * @throws BeansException in case of errors
1618 	 * @see RootBeanDefinition
1619 	 * @see ChildBeanDefinition
1620 	 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#getBeanDefinition
1621 	 */
1622 	protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
1623 
1624 	/**
1625 	 * Create a bean instance for the given merged bean definition (and arguments).
1626 	 * The bean definition will already have been merged with the parent definition
1627 	 * in case of a child definition.
1628 	 * <p>All bean retrieval methods delegate to this method for actual bean creation.
1629 	 * @param beanName the name of the bean
1630 	 * @param mbd the merged bean definition for the bean
1631 	 * @param args explicit arguments to use for constructor or factory method invocation
1632 	 * @return a new instance of the bean
1633 	 * @throws BeanCreationException if the bean could not be created
1634 	 */
1635 	protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
1636 			throws BeanCreationException;
1637 
1638 }