Save This Page
Home » spring-framework-2.5.6-with-dependencies » org.springframework » beans » factory » support » [javadoc | source]
    1   /*
    2    * Copyright 2002-2008 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.PropertyDescriptor;
   20   import java.lang.reflect.Constructor;
   21   import java.lang.reflect.InvocationTargetException;
   22   import java.lang.reflect.Method;
   23   import java.lang.reflect.Modifier;
   24   import java.security.AccessControlContext;
   25   import java.security.AccessController;
   26   import java.security.PrivilegedAction;
   27   import java.util.ArrayList;
   28   import java.util.Arrays;
   29   import java.util.HashMap;
   30   import java.util.HashSet;
   31   import java.util.Iterator;
   32   import java.util.LinkedHashSet;
   33   import java.util.LinkedList;
   34   import java.util.List;
   35   import java.util.Map;
   36   import java.util.Set;
   37   import java.util.TreeSet;
   38   
   39   import org.springframework.beans.BeanUtils;
   40   import org.springframework.beans.BeanWrapper;
   41   import org.springframework.beans.BeanWrapperImpl;
   42   import org.springframework.beans.BeansException;
   43   import org.springframework.beans.MutablePropertyValues;
   44   import org.springframework.beans.PropertyAccessorUtils;
   45   import org.springframework.beans.PropertyValue;
   46   import org.springframework.beans.PropertyValues;
   47   import org.springframework.beans.TypeConverter;
   48   import org.springframework.beans.factory.BeanClassLoaderAware;
   49   import org.springframework.beans.factory.BeanCreationException;
   50   import org.springframework.beans.factory.BeanCurrentlyInCreationException;
   51   import org.springframework.beans.factory.BeanDefinitionStoreException;
   52   import org.springframework.beans.factory.BeanFactory;
   53   import org.springframework.beans.factory.BeanFactoryAware;
   54   import org.springframework.beans.factory.BeanNameAware;
   55   import org.springframework.beans.factory.FactoryBean;
   56   import org.springframework.beans.factory.InitializingBean;
   57   import org.springframework.beans.factory.ObjectFactory;
   58   import org.springframework.beans.factory.UnsatisfiedDependencyException;
   59   import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
   60   import org.springframework.beans.factory.config.BeanDefinition;
   61   import org.springframework.beans.factory.config.BeanPostProcessor;
   62   import org.springframework.beans.factory.config.ConfigurableBeanFactory;
   63   import org.springframework.beans.factory.config.DependencyDescriptor;
   64   import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
   65   import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
   66   import org.springframework.beans.factory.config.TypedStringValue;
   67   import org.springframework.core.CollectionFactory;
   68   import org.springframework.core.MethodParameter;
   69   import org.springframework.core.PriorityOrdered;
   70   import org.springframework.util.ClassUtils;
   71   import org.springframework.util.ObjectUtils;
   72   import org.springframework.util.ReflectionUtils;
   73   import org.springframework.util.StringUtils;
   74   
   75   /**
   76    * Abstract bean factory superclass that implements default bean creation,
   77    * with the full capabilities specified by the {@link RootBeanDefinition} class.
   78    * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
   79    * interface in addition to AbstractBeanFactory's {@link #createBean} method.
   80    *
   81    * <p>Provides bean creation (with constructor resolution), property population,
   82    * wiring (including autowiring), and initialization. Handles runtime bean
   83    * references, resolves managed collections, calls initialization methods, etc.
   84    * Supports autowiring constructors, properties by name, and properties by type.
   85    *
   86    * <p>The main template method to be implemented by subclasses is
   87    * {@link #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)},
   88    * used for autowiring by type. In case of a factory which is capable of searching
   89    * its bean definitions, matching beans will typically be implemented through such
   90    * a search. For other factory styles, simplified matching algorithms can be implemented.
   91    *
   92    * <p>Note that this class does <i>not</i> assume or implement bean definition
   93    * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
   94    * of the {@link org.springframework.beans.factory.ListableBeanFactory} and
   95    * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
   96    * view of such a factory, respectively.
   97    *
   98    * @author Rod Johnson
   99    * @author Juergen Hoeller
  100    * @author Rob Harrop
  101    * @author Mark Fisher
  102    * @since 13.02.2004
  103    * @see RootBeanDefinition
  104    * @see DefaultListableBeanFactory
  105    * @see BeanDefinitionRegistry
  106    */
  107   public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
  108   		implements AutowireCapableBeanFactory {
  109   
  110   	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
  111   
  112   	/** Whether to automatically try to resolve circular references between beans */
  113   	private boolean allowCircularReferences = true;
  114   
  115   	/**
  116   	 * Whether to resort to injecting a raw bean instance in case of circular reference,
  117   	 * even if the injected bean eventually got wrapped.
  118   	 */
  119   	private boolean allowRawInjectionDespiteWrapping = false;
  120   
  121   	/**
  122   	 * Dependency types to ignore on dependency check and autowire, as Set of
  123   	 * Class objects: for example, String. Default is none.
  124   	 */
  125   	private final Set ignoredDependencyTypes = new HashSet();
  126   
  127   	/**
  128   	 * Dependency interfaces to ignore on dependency check and autowire, as Set of
  129   	 * Class objects. By default, only the BeanFactory interface is ignored.
  130   	 */
  131   	private final Set ignoredDependencyInterfaces = new HashSet();
  132   
  133   	/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
  134   	private final Map factoryBeanInstanceCache = CollectionFactory.createConcurrentMapIfPossible(16);
  135   
  136   	/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
  137   	private final Map filteredPropertyDescriptorsCache = new HashMap();
  138   
  139   
  140   	/**
  141   	 * Create a new AbstractAutowireCapableBeanFactory.
  142   	 */
  143   	public AbstractAutowireCapableBeanFactory() {
  144   		super();
  145   		ignoreDependencyInterface(BeanNameAware.class);
  146   		ignoreDependencyInterface(BeanFactoryAware.class);
  147   		ignoreDependencyInterface(BeanClassLoaderAware.class);
  148   	}
  149   
  150   	/**
  151   	 * Create a new AbstractAutowireCapableBeanFactory with the given parent.
  152   	 * @param parentBeanFactory parent bean factory, or <code>null</code> if none
  153   	 */
  154   	public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
  155   		this();
  156   		setParentBeanFactory(parentBeanFactory);
  157   	}
  158   
  159   
  160   	/**
  161   	 * Set the instantiation strategy to use for creating bean instances.
  162   	 * Default is CglibSubclassingInstantiationStrategy.
  163   	 * @see CglibSubclassingInstantiationStrategy
  164   	 */
  165   	public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
  166   		this.instantiationStrategy = instantiationStrategy;
  167   	}
  168   
  169   	/**
  170   	 * Return the instantiation strategy to use for creating bean instances.
  171   	 */
  172   	protected InstantiationStrategy getInstantiationStrategy() {
  173   		return this.instantiationStrategy;
  174   	}
  175   
  176   	/**
  177   	 * Set whether to allow circular references between beans - and automatically
  178   	 * try to resolve them.
  179   	 * <p>Note that circular reference resolution means that one of the involved beans
  180   	 * will receive a reference to another bean that is not fully initialized yet.
  181   	 * This can lead to subtle and not-so-subtle side effects on initialization;
  182   	 * it does work fine for many scenarios, though.
  183   	 * <p>Default is "true". Turn this off to throw an exception when encountering
  184   	 * a circular reference, disallowing them completely.
  185   	 * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
  186   	 * between your beans. Refactor your application logic to have the two beans
  187   	 * involved delegate to a third bean that encapsulates their common logic.
  188   	 */
  189   	public void setAllowCircularReferences(boolean allowCircularReferences) {
  190   		this.allowCircularReferences = allowCircularReferences;
  191   	}
  192   
  193   	/**
  194   	 * Set whether to allow the raw injection of a bean instance into some other
  195   	 * bean's property, despite the injected bean eventually getting wrapped
  196   	 * (for example, through AOP auto-proxying).
  197   	 * <p>This will only be used as a last resort in case of a circular reference
  198   	 * that cannot be resolved otherwise: essentially, preferring a raw instance
  199   	 * getting injected over a failure of the entire bean wiring process.
  200   	 * <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped
  201   	 * raw beans injected into some of your references, which was Spring 1.2's
  202   	 * (arguably unclean) default behavior.
  203   	 * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
  204   	 * between your beans, in particular with auto-proxying involved.
  205   	 * @see #setAllowCircularReferences
  206   	 */
  207   	public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) {
  208   		this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
  209   	}
  210   
  211   	/**
  212   	 * Ignore the given dependency type for autowiring:
  213   	 * for example, String. Default is none.
  214   	 */
  215   	public void ignoreDependencyType(Class type) {
  216   		this.ignoredDependencyTypes.add(type);
  217   	}
  218   
  219   	/**
  220   	 * Ignore the given dependency interface for autowiring.
  221   	 * <p>This will typically be used by application contexts to register
  222   	 * dependencies that are resolved in other ways, like BeanFactory through
  223   	 * BeanFactoryAware or ApplicationContext through ApplicationContextAware.
  224   	 * <p>By default, only the BeanFactoryAware interface is ignored.
  225   	 * For further types to ignore, invoke this method for each type.
  226   	 * @see org.springframework.beans.factory.BeanFactoryAware
  227   	 * @see org.springframework.context.ApplicationContextAware
  228   	 */
  229   	public void ignoreDependencyInterface(Class ifc) {
  230   		this.ignoredDependencyInterfaces.add(ifc);
  231   	}
  232   
  233   
  234   	public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
  235   		super.copyConfigurationFrom(otherFactory);
  236   		if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
  237   			AbstractAutowireCapableBeanFactory otherAutowireFactory =
  238   					(AbstractAutowireCapableBeanFactory) otherFactory;
  239   			this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
  240   			this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
  241   			this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
  242   			this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
  243   		}
  244   	}
  245   
  246   
  247   	//-------------------------------------------------------------------------
  248   	// Typical methods for creating and populating external bean instances
  249   	//-------------------------------------------------------------------------
  250   
  251   	public Object createBean(Class beanClass) throws BeansException {
  252   		// Use prototype bean definition, to avoid registering bean as dependent bean.
  253   		RootBeanDefinition bd = new RootBeanDefinition(beanClass);
  254   		bd.setScope(SCOPE_PROTOTYPE);
  255   		return createBean(beanClass.getName(), bd, null);
  256   	}
  257   
  258   	public void autowireBean(Object existingBean) {
  259   		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
  260   		RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
  261   		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  262   		BeanWrapper bw = new BeanWrapperImpl(existingBean);
  263   		initBeanWrapper(bw);
  264   		populateBean(bd.getBeanClass().getName(), bd, bw);
  265   	}
  266   
  267   	public Object configureBean(Object existingBean, String beanName) throws BeansException {
  268   		markBeanAsCreated(beanName);
  269   		BeanDefinition mbd = getMergedBeanDefinition(beanName);
  270   		RootBeanDefinition bd = null;
  271   		if (mbd instanceof RootBeanDefinition) {
  272   			RootBeanDefinition rbd = (RootBeanDefinition) mbd;
  273   			if (SCOPE_PROTOTYPE.equals(rbd.getScope())) {
  274   				bd = rbd;
  275   			}
  276   		}
  277   		if (bd == null) {
  278   			bd = new RootBeanDefinition(mbd);
  279   			bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  280   		}
  281   		BeanWrapper bw = new BeanWrapperImpl(existingBean);
  282   		initBeanWrapper(bw);
  283   		populateBean(beanName, bd, bw);
  284   		return initializeBean(beanName, existingBean, bd);
  285   	}
  286   
  287   	public Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException {
  288   		return resolveDependency(descriptor, beanName, null, null);
  289   	}
  290   
  291   
  292   	//-------------------------------------------------------------------------
  293   	// Specialized methods for fine-grained control over the bean lifecycle
  294   	//-------------------------------------------------------------------------
  295   
  296   	public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
  297   		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
  298   		RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
  299   		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  300   		return createBean(beanClass.getName(), bd, null);
  301   	}
  302   
  303   	public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
  304   		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
  305   		RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
  306   		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  307   		if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
  308   			return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
  309   		}
  310   		else {
  311   			Object bean = getInstantiationStrategy().instantiate(bd, null, this);
  312   			populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
  313   			return bean;
  314   		}
  315   	}
  316   
  317   	public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
  318   			throws BeansException {
  319   
  320   		if (autowireMode == AUTOWIRE_CONSTRUCTOR) {
  321   			throw new IllegalArgumentException("AUTOWIRE_CONSTRUCTOR not supported for existing bean instance");
  322   		}
  323   		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
  324   		RootBeanDefinition bd =
  325   				new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck);
  326   		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
  327   		BeanWrapper bw = new BeanWrapperImpl(existingBean);
  328   		initBeanWrapper(bw);
  329   		populateBean(bd.getBeanClass().getName(), bd, bw);
  330   	}
  331   
  332   	public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
  333   		markBeanAsCreated(beanName);
  334   		BeanDefinition bd = getMergedBeanDefinition(beanName);
  335   		BeanWrapper bw = new BeanWrapperImpl(existingBean);
  336   		initBeanWrapper(bw);
  337   		applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
  338   	}
  339   
  340   	public Object initializeBean(Object existingBean, String beanName) {
  341   		return initializeBean(beanName, existingBean, null);
  342   	}
  343   
  344   	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
  345   			throws BeansException {
  346   
  347   		Object result = existingBean;
  348   		for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  349   			BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  350   			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
  351   		}
  352   		return result;
  353   	}
  354   
  355   	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  356   			throws BeansException {
  357   
  358   		Object result = existingBean;
  359   		for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  360   			BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  361   			result = beanProcessor.postProcessAfterInitialization(result, beanName);
  362   		}
  363   		return result;
  364   	}
  365   
  366   
  367   	//---------------------------------------------------------------------
  368   	// Implementation of relevant AbstractBeanFactory template methods
  369   	//---------------------------------------------------------------------
  370   
  371   	/**
  372   	 * Central method of this class: creates a bean instance,
  373   	 * populates the bean instance, applies post-processors, etc.
  374   	 * @see #doCreateBean
  375   	 */
  376   	protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
  377   			throws BeanCreationException {
  378   
  379   		AccessControlContext acc = AccessController.getContext();
  380   		return AccessController.doPrivileged(new PrivilegedAction() {
  381   			public Object run() {
  382   				if (logger.isDebugEnabled()) {
  383   					logger.debug("Creating instance of bean '" + beanName + "'");
  384   				}
  385   				// Make sure bean class is actually resolved at this point.
  386   				resolveBeanClass(mbd, beanName);
  387   
  388   				// Prepare method overrides.
  389   				try {
  390   					mbd.prepareMethodOverrides();
  391   				}
  392   				catch (BeanDefinitionValidationException ex) {
  393   					throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
  394   							beanName, "Validation of method overrides failed", ex);
  395   				}
  396   
  397   				try {
  398   					// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  399   					Object bean = resolveBeforeInstantiation(beanName, mbd);
  400   					if (bean != null) {
  401   						return bean;
  402   					}
  403   				}
  404   				catch (Throwable ex) {
  405   					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  406   							"BeanPostProcessor before instantiation of bean failed", ex);
  407   				}
  408   
  409   				Object beanInstance = doCreateBean(beanName, mbd, args);
  410   				if (logger.isDebugEnabled()) {
  411   					logger.debug("Finished creating instance of bean '" + beanName + "'");
  412   				}
  413   				return beanInstance;
  414   			}
  415   		}, acc);
  416   	}
  417   
  418   	/**
  419   	 * Actually create the specified bean. Pre-creation processing has already happened
  420   	 * at this point, e.g. checking <code>postProcessBeforeInstantiation</code> callbacks.
  421   	 * <p>Differentiates between default bean instantiation, use of a
  422   	 * factory method, and autowiring a constructor.
  423   	 * @param beanName the name of the bean
  424   	 * @param mbd the merged bean definition for the bean
  425   	 * @param args arguments to use if creating a prototype using explicit arguments to a
  426   	 * static factory method. This parameter must be <code>null</code> except in this case.
  427   	 * @return a new instance of the bean
  428   	 * @throws BeanCreationException if the bean could not be created
  429   	 * @see #instantiateBean
  430   	 * @see #instantiateUsingFactoryMethod
  431   	 * @see #autowireConstructor
  432   	 */
  433   	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
  434   		// Instantiate the bean.
  435   		BeanWrapper instanceWrapper = null;
  436   		if (mbd.isSingleton()) {
  437   			instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
  438   		}
  439   		if (instanceWrapper == null) {
  440   			instanceWrapper = createBeanInstance(beanName, mbd, args);
  441   		}
  442   		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
  443   		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
  444   
  445   		// Allow post-processors to modify the merged bean definition.
  446   		synchronized (mbd.postProcessingLock) {
  447   			if (!mbd.postProcessed) {
  448   				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  449   				mbd.postProcessed = true;
  450   			}
  451   		}
  452   
  453   		// Eagerly cache singletons to be able to resolve circular references
  454   		// even when triggered by lifecycle interfaces like BeanFactoryAware.
  455   		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  456   				isSingletonCurrentlyInCreation(beanName));
  457   		if (earlySingletonExposure) {
  458   			if (logger.isDebugEnabled()) {
  459   				logger.debug("Eagerly caching bean '" + beanName +
  460   						"' to allow for resolving potential circular references");
  461   			}
  462   			addSingletonFactory(beanName, new ObjectFactory() {
  463   				public Object getObject() throws BeansException {
  464   					return getEarlyBeanReference(beanName, mbd, bean);
  465   				}
  466   			});
  467   		}
  468   
  469   		// Initialize the bean instance.
  470   		Object exposedObject = bean;
  471   		try {
  472   			populateBean(beanName, mbd, instanceWrapper);
  473   			exposedObject = initializeBean(beanName, exposedObject, mbd);
  474   		}
  475   		catch (Throwable ex) {
  476   			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  477   				throw (BeanCreationException) ex;
  478   			}
  479   			else {
  480   				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  481   			}
  482   		}
  483   
  484   		if (earlySingletonExposure) {
  485   			Object earlySingletonReference = getSingleton(beanName, false);
  486   			if (earlySingletonReference != null) {
  487   				if (exposedObject == bean) {
  488   					exposedObject = earlySingletonReference;
  489   				}
  490   				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  491   					String[] dependentBeans = getDependentBeans(beanName);
  492   					Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
  493   					for (int i = 0; i < dependentBeans.length; i++) {
  494   						String dependentBean = dependentBeans[i];
  495   						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  496   							actualDependentBeans.add(dependentBean);
  497   						}
  498   					}
  499   					if (!actualDependentBeans.isEmpty()) {
  500   						throw new BeanCurrentlyInCreationException(beanName,
  501   								"Bean with name '" + beanName + "' has been injected into other beans [" +
  502   								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  503   								"] in its raw version as part of a circular reference, but has eventually been " +
  504   								"wrapped. This means that said other beans do not use the final version of the " +
  505   								"bean. This is often the result of over-eager type matching - consider using " +
  506   								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
  507   					}
  508   				}
  509   			}
  510   		}
  511   
  512   		// Register bean as disposable.
  513   		registerDisposableBeanIfNecessary(beanName, bean, mbd);
  514   
  515   		return exposedObject;
  516   	}
  517   
  518   	protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
  519   		Class beanClass = null;
  520   		if (mbd.getFactoryMethodName() != null) {
  521   			beanClass = getTypeForFactoryMethod(beanName, mbd, typesToMatch);
  522   		}
  523   		else {
  524   			beanClass = resolveBeanClass(mbd, beanName, typesToMatch);
  525   		}
  526   		// Apply SmartInstantiationAwareBeanPostProcessors to predict the
  527   		// eventual type after a before-instantiation shortcut.
  528   		if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  529   			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
  530   				BeanPostProcessor bp = (BeanPostProcessor) it.next();
  531   				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
  532   					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
  533   					Class processedType = ibp.predictBeanType(beanClass, beanName);
  534   					if (processedType != null) {
  535   						return processedType;
  536   					}
  537   				}
  538   			}
  539   		}
  540   		return beanClass;
  541   	}
  542   
  543   	/**
  544   	 * Determine the bean type for the given bean definition which is based on
  545   	 * a factory method. Only called if there is no singleton instance registered
  546   	 * for the target bean already.
  547   	 * <p>This implementation determines the type matching {@link #createBean}'s
  548   	 * different creation strategies. As far as possible, we'll perform static
  549   	 * type checking to avoid creation of the target bean.
  550   	 * @param beanName the name of the bean (for error handling purposes)
  551   	 * @param mbd the merged bean definition for the bean
  552   	 * @param typesToMatch the types to match in case of internal type matching purposes
  553   	 * (also signals that the returned <code>Class</code> will never be exposed to application code)
  554   	 * @return the type for the bean if determinable, or <code>null</code> else
  555   	 * @see #createBean
  556   	 */
  557   	protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
  558   		Class factoryClass = null;
  559   		boolean isStatic = true;
  560   
  561   		String factoryBeanName = mbd.getFactoryBeanName();
  562   		if (factoryBeanName != null) {
  563   			if (factoryBeanName.equals(beanName)) {
  564   				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
  565   						"factory-bean reference points back to the same bean definition");
  566   			}
  567   			// Check declared factory method return type on factory class.
  568   			factoryClass = getType(factoryBeanName);
  569   			isStatic = false;
  570   		}
  571   		else {
  572   			// Check declared factory method return type on bean class.
  573   			factoryClass = resolveBeanClass(mbd, beanName, typesToMatch);
  574   		}
  575   
  576   		if (factoryClass == null) {
  577   			return null;
  578   		}
  579   
  580   		// If all factory methods have the same return type, return that type.
  581   		// Can't clearly figure out exact method due to type converting / autowiring!
  582   		int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount();
  583   		Method[] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass);
  584   		Set returnTypes = new HashSet(1);
  585   		for (int i = 0; i < candidates.length; i++) {
  586   			Method factoryMethod = candidates[i];
  587   			if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic &&
  588   					factoryMethod.getName().equals(mbd.getFactoryMethodName()) &&
  589   					factoryMethod.getParameterTypes().length >= minNrOfArgs) {
  590   				returnTypes.add(factoryMethod.getReturnType());
  591   			}
  592   		}
  593   
  594   		if (returnTypes.size() == 1) {
  595   			// Clear return type found: all factory methods return same type.
  596   			return (Class) returnTypes.iterator().next();
  597   		}
  598   		else {
  599   			// Ambiguous return types found: return null to indicate "not determinable".
  600   			return null;
  601   		}
  602   	}
  603   
  604   	/**
  605   	 * This implementation checks the FactoryBean's <code>getObjectType</code> method
  606   	 * on a plain instance of the FactoryBean, without bean properties applied yet.
  607   	 * If this doesn't return a type yet, a full creation of the FactoryBean is
  608   	 * used as fallback (through delegation to the superclass's implementation).
  609   	 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
  610   	 * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
  611   	 * it will be fully created to check the type of its exposed object.
  612   	 */
  613   	protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
  614   		FactoryBean fb = (mbd.isSingleton() ?
  615   				getSingletonFactoryBeanForTypeCheck(beanName, mbd) :
  616   				getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));
  617   
  618   		if (fb != null) {
  619   			// Try to obtain the FactoryBean's object type from this early stage of the instance.
  620   			Class objectType = getTypeForFactoryBean(fb);
  621   			if (objectType != null) {
  622   				return objectType;
  623   			}
  624   		}
  625   
  626   		// No type found - fall back to full creation of the FactoryBean instance.
  627   		return super.getTypeForFactoryBean(beanName, mbd);
  628   	}
  629   
  630   	/**
  631   	 * Obtain a reference for early access to the specified bean,
  632   	 * typically for the purpose of resolving a circular reference.
  633   	 * @param beanName the name of the bean (for error handling purposes)
  634   	 * @param mbd the merged bean definition for the bean
  635   	 * @param bean the raw bean instance
  636   	 * @return the object to expose as bean reference
  637   	 */
  638   	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
  639   		Object exposedObject = bean;
  640   		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  641   			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
  642   				BeanPostProcessor bp = (BeanPostProcessor) it.next();
  643   				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
  644   					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
  645   					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
  646   				}
  647   			}
  648   		}
  649   		return exposedObject;
  650   	}
  651   
  652   
  653   	//---------------------------------------------------------------------
  654   	// Implementation methods
  655   	//---------------------------------------------------------------------
  656   
  657   	/**
  658   	 * Obtain a "shortcut" singleton FactoryBean instance to use for a
  659   	 * <code>getObjectType()</code> call, without full initialization
  660   	 * of the FactoryBean.
  661   	 * @param beanName the name of the bean
  662   	 * @param mbd the bean definition for the bean
  663   	 * @return the FactoryBean instance, or <code>null</code> to indicate
  664   	 * that we couldn't obtain a shortcut FactoryBean instance
  665   	 */
  666   	private FactoryBean getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
  667   		synchronized (getSingletonMutex()) {
  668   			BeanWrapper bw = (BeanWrapper) this.factoryBeanInstanceCache.get(beanName);
  669   			if (bw != null) {
  670   				return (FactoryBean) bw.getWrappedInstance();
  671   			}
  672   			if (isSingletonCurrentlyInCreation(beanName)) {
  673   				return null;
  674   			}
  675   			Object instance = null;
  676   			try {
  677   				// Mark this bean as currently in creation, even if just partially.
  678   				beforeSingletonCreation(beanName);
  679   				// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  680   				instance = resolveBeforeInstantiation(beanName, mbd);
  681   				if (instance == null) {
  682   					bw = createBeanInstance(beanName, mbd, null);
  683   					instance = bw.getWrappedInstance();
  684   				}
  685   			}
  686   			finally {
  687   				// Finished partial creation of this bean.
  688   				afterSingletonCreation(beanName);
  689   			}
  690   			FactoryBean fb = getFactoryBean(beanName, instance);
  691   			if (bw != null) {
  692   				this.factoryBeanInstanceCache.put(beanName, bw);
  693   			}
  694   			return fb;
  695   		}
  696   	}
  697   
  698   	/**
  699   	 * Obtain a "shortcut" non-singleton FactoryBean instance to use for a
  700   	 * <code>getObjectType()</code> call, without full initialization
  701   	 * of the FactoryBean.
  702   	 * @param beanName the name of the bean
  703   	 * @param mbd the bean definition for the bean
  704   	 * @return the FactoryBean instance, or <code>null</code> to indicate
  705   	 * that we couldn't obtain a shortcut FactoryBean instance
  706   	 */
  707   	private FactoryBean getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
  708   		if (isPrototypeCurrentlyInCreation(beanName)) {
  709   			return null;
  710   		}
  711   		Object instance = null;
  712   		try {
  713   			// Mark this bean as currently in creation, even if just partially.
  714   			beforePrototypeCreation(beanName);
  715   			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  716   			instance = resolveBeforeInstantiation(beanName, mbd);
  717   			if (instance == null) {
  718   				BeanWrapper bw = createBeanInstance(beanName, mbd, null);
  719   				instance = bw.getWrappedInstance();
  720   			}
  721   		}
  722   		finally {
  723   			// Finished partial creation of this bean.
  724   			afterPrototypeCreation(beanName);
  725   		}
  726   		return getFactoryBean(beanName, instance);
  727   	}
  728   
  729   	/**
  730   	 * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
  731   	 * invoking their <code>postProcessMergedBeanDefinition</code> methods.
  732   	 * @param mbd the merged bean definition for the bean
  733   	 * @param beanType the actual type of the managed bean instance
  734   	 * @param beanName the name of the bean
  735   	 * @throws BeansException if any post-processing failed
  736   	 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
  737   	 */
  738   	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName)
  739   			throws BeansException {
  740   
  741   		for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  742   			BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  743   			if (beanProcessor instanceof MergedBeanDefinitionPostProcessor) {
  744   				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) beanProcessor;
  745   				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
  746   			}
  747   		}
  748   	}
  749   
  750   	/**
  751   	 * Apply before-instantiation post-processors, resolving whether there is a
  752   	 * before-instantiation shortcut for the specified bean.
  753   	 * @param beanName the name of the bean
  754   	 * @param mbd the bean definition for the bean
  755   	 * @return the shortcut-determined bean instance, or <code>null</code> if none
  756   	 */
  757   	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  758   		Object bean = null;
  759   		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  760   			// Make sure bean class is actually resolved at this point.
  761   			if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  762   				bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
  763   				if (bean != null) {
  764   					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  765   				}
  766   			}
  767   			mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
  768   		}
  769   		return bean;
  770   	}
  771   
  772   	/**
  773   	 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
  774   	 * (by class and name), invoking their <code>postProcessBeforeInstantiation</code> methods.
  775   	 * <p>Any returned object will be used as the bean instead of actually instantiating
  776   	 * the target bean. A <code>null</code> return value from the post-processor will
  777   	 * result in the target bean being instantiated.
  778   	 * @param beanClass the class of the bean to be instantiated
  779   	 * @param beanName the name of the bean
  780   	 * @return the bean object to use instead of a default instance of the target bean, or <code>null</code>
  781   	 * @throws BeansException if any post-processing failed
  782   	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
  783   	 */
  784   	protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName)
  785   			throws BeansException {
  786   
  787   		for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  788   			BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  789   			if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
  790   				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
  791   				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
  792   				if (result != null) {
  793   					return result;
  794   				}
  795   			}
  796   		}
  797   		return null;
  798   	}
  799   
  800   	/**
  801   	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
  802   	 * factory method, constructor autowiring, or simple instantiation.
  803   	 * @param beanName the name of the bean
  804   	 * @param mbd the bean definition for the bean
  805   	 * @param args arguments to use if creating a prototype using explicit arguments to a
  806   	 * static factory method. It is invalid to use a non-null args value in any other case.
  807   	 * @return BeanWrapper for the new instance
  808   	 * @see #instantiateUsingFactoryMethod
  809   	 * @see #autowireConstructor
  810   	 * @see #instantiateBean
  811   	 */
  812   	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
  813   		// Make sure bean class is actually resolved at this point.
  814   		Class beanClass = resolveBeanClass(mbd, beanName);
  815   
  816   		if (mbd.getFactoryMethodName() != null)  {
  817   			return instantiateUsingFactoryMethod(beanName, mbd, args);
  818   		}
  819   
  820   		// Shortcut when re-creating the same bean...
  821   		if (mbd.resolvedConstructorOrFactoryMethod != null) {
  822   			if (mbd.constructorArgumentsResolved) {
  823   				return autowireConstructor(beanName, mbd, null, args);
  824   			}
  825   			else {
  826   				return instantiateBean(beanName, mbd);
  827   			}
  828   		}
  829   
  830   		// Need to determine the constructor...
  831   		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  832   		if (ctors != null ||
  833   				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
  834   				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
  835   			return autowireConstructor(beanName, mbd, ctors, args);
  836   		}
  837   
  838   		// No special handling: simply use no-arg constructor.
  839   		return instantiateBean(beanName, mbd);
  840   	}
  841   
  842   	/**
  843   	 * Determine candidate constructors to use for the given bean, checking all registered
  844   	 * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
  845   	 * @param beanClass the raw class of the bean
  846   	 * @param beanName the name of the bean
  847   	 * @return the candidate constructors, or <code>null</code> if none specified
  848   	 * @throws org.springframework.beans.BeansException in case of errors
  849   	 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
  850   	 */
  851   	protected Constructor[] determineConstructorsFromBeanPostProcessors(Class beanClass, String beanName)
  852   			throws BeansException {
  853   
  854   		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
  855   			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  856   				BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  857   				if (beanProcessor instanceof SmartInstantiationAwareBeanPostProcessor) {
  858   					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) beanProcessor;
  859   					Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
  860   					if (ctors != null) {
  861   						return ctors;
  862   					}
  863   				}
  864   			}
  865   		}
  866   		return null;
  867   	}
  868   
  869   	/**
  870   	 * Instantiate the given bean using its default constructor.
  871   	 * @param beanName the name of the bean
  872   	 * @param mbd the bean definition for the bean
  873   	 * @return BeanWrapper for the new instance
  874   	 */
  875   	protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
  876   		try {
  877   			Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
  878   			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
  879   			initBeanWrapper(bw);
  880   			return bw;
  881   		}
  882   		catch (Throwable ex) {
  883   			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
  884   		}
  885   	}
  886   
  887   	/**
  888   	 * Instantiate the bean using a named factory method. The method may be static, if the
  889   	 * mbd parameter specifies a class, rather than a factoryBean, or an instance variable
  890   	 * on a factory object itself configured using Dependency Injection.
  891   	 * @param beanName the name of the bean
  892   	 * @param mbd the bean definition for the bean
  893   	 * @param explicitArgs argument values passed in programmatically via the getBean method,
  894   	 * or <code>null</code> if none (-> use constructor argument values from bean definition)
  895   	 * @return BeanWrapper for the new instance
  896   	 * @see #getBean(String, Object[])
  897   	 */
  898   	protected BeanWrapper instantiateUsingFactoryMethod(
  899   			String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
  900   
  901   		ConstructorResolver constructorResolver =
  902   				new ConstructorResolver(this, this, getInstantiationStrategy(), getCustomTypeConverter());
  903   		return constructorResolver.instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
  904   	}
  905   
  906   	/**
  907   	 * "autowire constructor" (with constructor arguments by type) behavior.
  908   	 * Also applied if explicit constructor argument values are specified,
  909   	 * matching all remaining arguments with beans from the bean factory.
  910   	 * <p>This corresponds to constructor injection: In this mode, a Spring
  911   	 * bean factory is able to host components that expect constructor-based
  912   	 * dependency resolution.
  913   	 * @param beanName the name of the bean
  914   	 * @param mbd the bean definition for the bean
  915   	 * @param ctors the chosen candidate constructors
  916   	 * @param explicitArgs argument values passed in programmatically via the getBean method,
  917   	 * or <code>null</code> if none (-> use constructor argument values from bean definition)
  918   	 * @return BeanWrapper for the new instance
  919   	 */
  920   	protected BeanWrapper autowireConstructor(
  921   			String beanName, RootBeanDefinition mbd, Constructor[] ctors, Object[] explicitArgs) {
  922   
  923   		ConstructorResolver constructorResolver =
  924   				new ConstructorResolver(this, this, getInstantiationStrategy(), getCustomTypeConverter());
  925   		return constructorResolver.autowireConstructor(beanName, mbd, ctors, explicitArgs);
  926   	}
  927   
  928   	/**
  929   	 * Populate the bean instance in the given BeanWrapper with the property values
  930   	 * from the bean definition.
  931   	 * @param beanName the name of the bean
  932   	 * @param mbd the bean definition for the bean
  933   	 * @param bw BeanWrapper with bean instance
  934   	 */
  935   	protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
  936   		PropertyValues pvs = mbd.getPropertyValues();
  937   
  938   		if (bw == null) {
  939   			if (!pvs.isEmpty()) {
  940   				throw new BeanCreationException(
  941   						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
  942   			}
  943   			else {
  944   				// Skip property population phase for null instance.
  945   				return;
  946   			}
  947   		}
  948   
  949   		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
  950   		// state of the bean before properties are set. This can be used, for example,
  951   		// to support styles of field injection.
  952   		boolean continueWithPropertyPopulation = true;
  953   
  954   		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  955   			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
  956   				BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  957   				if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
  958   					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
  959   					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  960   						continueWithPropertyPopulation = false;
  961   						break;
  962   					}
  963   				}
  964   			}
  965   		}
  966   
  967   		if (!continueWithPropertyPopulation) {
  968   			return;
  969   		}
  970   
  971   		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
  972   				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
  973   			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  974   
  975   			// Add property values based on autowire by name if applicable.
  976   			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
  977   				autowireByName(beanName, mbd, bw, newPvs);
  978   			}
  979   
  980   			// Add property values based on autowire by type if applicable.
  981   			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
  982   				autowireByType(beanName, mbd, bw, newPvs);
  983   			}
  984   
  985   			pvs = newPvs;
  986   		}
  987   
  988   		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  989   		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
  990   
  991   		if (hasInstAwareBpps || needsDepCheck) {
  992   			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
  993   			if (hasInstAwareBpps) {
  994   				for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
  995   					BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
  996   					if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
  997   						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
  998   						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  999   						if (pvs == null) {
 1000   							return;
 1001   						}
 1002   					}
 1003   				}
 1004   			}
 1005   			if (needsDepCheck) {
 1006   				checkDependencies(beanName, mbd, filteredPds, pvs);
 1007   			}
 1008   		}
 1009   
 1010   		applyPropertyValues(beanName, mbd, bw, pvs);
 1011   	}
 1012   
 1013   	/**
 1014   	 * Fill in any missing property values with references to
 1015   	 * other beans in this factory if autowire is set to "byName".
 1016   	 * @param beanName the name of the bean we're wiring up.
 1017   	 * Useful for debugging messages; not used functionally.
 1018   	 * @param mbd bean definition to update through autowiring
 1019   	 * @param bw BeanWrapper from which we can obtain information about the bean
 1020   	 * @param pvs the PropertyValues to register wired objects with
 1021   	 */
 1022   	protected void autowireByName(
 1023   			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
 1024   
 1025   		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
 1026   		for (int i = 0; i < propertyNames.length; i++) {
 1027   			String propertyName = propertyNames[i];
 1028   			if (containsBean(propertyName)) {
 1029   				Object bean = getBean(propertyName);
 1030   				pvs.addPropertyValue(propertyName, bean);
 1031   				registerDependentBean(propertyName, beanName);
 1032   				if (logger.isDebugEnabled()) {
 1033   					logger.debug("Added autowiring by name from bean name '" + beanName +
 1034   						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
 1035   				}
 1036   			}
 1037   			else {
 1038   				if (logger.isTraceEnabled()) {
 1039   					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
 1040   							"' by name: no matching bean found");
 1041   				}
 1042   			}
 1043   		}
 1044   	}
 1045   
 1046   	/**
 1047   	 * Abstract method defining "autowire by type" (bean properties by type) behavior.
 1048   	 * <p>This is like PicoContainer default, in which there must be exactly one bean
 1049   	 * of the property type in the bean factory. This makes bean factories simple to
 1050   	 * configure for small namespaces, but doesn't work as well as standard Spring
 1051   	 * behavior for bigger applications.
 1052   	 * @param beanName the name of the bean to autowire by type
 1053   	 * @param mbd the merged bean definition to update through autowiring
 1054   	 * @param bw BeanWrapper from which we can obtain information about the bean
 1055   	 * @param pvs the PropertyValues to register wired objects with
 1056   	 */
 1057   	protected void autowireByType(
 1058   			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
 1059   
 1060   		TypeConverter converter = getCustomTypeConverter();
 1061   		if (converter == null) {
 1062   			converter = bw;
 1063   		}
 1064   
 1065   		Set autowiredBeanNames = new LinkedHashSet(4);
 1066   		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
 1067   		for (int i = 0; i < propertyNames.length; i++) {
 1068   			String propertyName = propertyNames[i];
 1069   			try {
 1070   				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
 1071   				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
 1072   				// Do not allow eager init for type matching in case of a prioritized post-processor.
 1073   				boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
 1074   				DependencyDescriptor desc = new DependencyDescriptor(methodParam, false, eager);
 1075   
 1076   				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
 1077   				if (autowiredArgument != null) {
 1078   					pvs.addPropertyValue(propertyName, autowiredArgument);
 1079   				}
 1080   				for (Iterator it = autowiredBeanNames.iterator(); it.hasNext();) {
 1081   					String autowiredBeanName = (String) it.next();
 1082   					registerDependentBean(autowiredBeanName, beanName);
 1083   					if (logger.isDebugEnabled()) {
 1084   						logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
 1085   								propertyName + "' to bean named '" + autowiredBeanName + "'");
 1086   					}
 1087   				}
 1088   				autowiredBeanNames.clear();
 1089   			}
 1090   			catch (BeansException ex) {
 1091   				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
 1092   			}
 1093   		}
 1094   	}
 1095   
 1096   
 1097   	/**
 1098   	 * Return an array of non-simple bean properties that are unsatisfied.
 1099   	 * These are probably unsatisfied references to other beans in the
 1100   	 * factory. Does not include simple properties like primitives or Strings.
 1101   	 * @param mbd the merged bean definition the bean was created with
 1102   	 * @param bw the BeanWrapper the bean was created with
 1103   	 * @return an array of bean property names
 1104   	 * @see org.springframework.beans.BeanUtils#isSimpleProperty
 1105   	 */
 1106   	protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
 1107   		Set result = new TreeSet();
 1108   		PropertyValues pvs = mbd.getPropertyValues();
 1109   		PropertyDescriptor[] pds = bw.getPropertyDescriptors();
 1110   		for (int i = 0; i < pds.length; i++) {
 1111   			if (pds[i].getWriteMethod() != null && !isExcludedFromDependencyCheck(pds[i]) &&
 1112   					!pvs.contains(pds[i].getName()) && !BeanUtils.isSimpleProperty(pds[i].getPropertyType())) {
 1113   				result.add(pds[i].getName());
 1114   			}
 1115   		}
 1116   		return StringUtils.toStringArray(result);
 1117   	}
 1118   
 1119   	/**
 1120   	 * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
 1121   	 * excluding ignored dependency types or properties defined on ignored
 1122   	 * dependency interfaces.
 1123   	 * @param bw the BeanWrapper the bean was created with
 1124   	 * @return the filtered PropertyDescriptors
 1125   	 * @see #isExcludedFromDependencyCheck
 1126   	 */
 1127   	protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
 1128   		synchronized (this.filteredPropertyDescriptorsCache) {
 1129   			PropertyDescriptor[] filtered = (PropertyDescriptor[])
 1130   					this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
 1131   			if (filtered == null) {
 1132   				List pds = new LinkedList(Arrays.asList(bw.getPropertyDescriptors()));
 1133   				for (Iterator it = pds.iterator(); it.hasNext();) {
 1134   					PropertyDescriptor pd = (PropertyDescriptor) it.next();
 1135   					if (isExcludedFromDependencyCheck(pd)) {
 1136   						it.remove();
 1137   					}
 1138   				}
 1139   				filtered = (PropertyDescriptor[]) pds.toArray(new PropertyDescriptor[pds.size()]);
 1140   				this.filteredPropertyDescriptorsCache.put(bw.getWrappedClass(), filtered);
 1141   			}
 1142   			return filtered;
 1143   		}
 1144   	}
 1145   
 1146   	/**
 1147   	 * Determine whether the given bean property is excluded from dependency checks.
 1148   	 * <p>This implementation excludes properties defined by CGLIB and
 1149   	 * properties whose type matches an ignored dependency type or which
 1150   	 * are defined by an ignored dependency interface.
 1151   	 * @param pd the PropertyDescriptor of the bean property
 1152   	 * @return whether the bean property is excluded
 1153   	 * @see #ignoreDependencyType(Class)
 1154   	 * @see #ignoreDependencyInterface(Class)
 1155   	 */
 1156   	protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
 1157   		return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
 1158   				this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
 1159   				AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
 1160   	}
 1161   
 1162   	/**
 1163   	 * Perform a dependency check that all properties exposed have been set,
 1164   	 * if desired. Dependency checks can be objects (collaborating beans),
 1165   	 * simple (primitives and String), or all (both).
 1166   	 * @param beanName the name of the bean
 1167   	 * @param mbd the merged bean definition the bean was created with
 1168   	 * @param pds the relevant property descriptors for the target bean
 1169   	 * @param pvs the property values to be applied to the bean
 1170   	 * @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor)
 1171   	 */
 1172   	protected void checkDependencies(
 1173   			String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs)
 1174   			throws UnsatisfiedDependencyException {
 1175   
 1176   		int dependencyCheck = mbd.getDependencyCheck();
 1177   		for (int i = 0; i < pds.length; i++) {
 1178   			if (pds[i].getWriteMethod() != null && !pvs.contains(pds[i].getName())) {
 1179   				boolean isSimple = BeanUtils.isSimpleProperty(pds[i].getPropertyType());
 1180   				boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) ||
 1181   					(isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
 1182   					(!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
 1183   				if (unsatisfied) {
 1184   					throw new UnsatisfiedDependencyException(
 1185   							mbd.getResourceDescription(), beanName, pds[i].getName(),
 1186   							"Set this property value or disable dependency checking for this bean.");
 1187   				}
 1188   			}
 1189   		}
 1190   	}
 1191   
 1192   	/**
 1193   	 * Apply the given property values, resolving any runtime references
 1194   	 * to other beans in this bean factory. Must use deep copy, so we
 1195   	 * don't permanently modify this property.
 1196   	 * @param beanName the bean name passed for better exception information
 1197   	 * @param mbd the merged bean definition
 1198   	 * @param bw the BeanWrapper wrapping the target object
 1199   	 * @param pvs the new property values
 1200   	 */
 1201   	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
 1202   		if (pvs == null || pvs.isEmpty()) {
 1203   			return;
 1204   		}
 1205   
 1206   		MutablePropertyValues mpvs = null;
 1207   		List original = null;
 1208   
 1209   		if (pvs instanceof MutablePropertyValues) {
 1210   			mpvs = (MutablePropertyValues) pvs;
 1211   			if (mpvs.isConverted()) {
 1212   				// Shortcut: use the pre-converted values as-is.
 1213   				try {
 1214   					bw.setPropertyValues(mpvs);
 1215   					return;
 1216   				}
 1217   				catch (BeansException ex) {
 1218   					throw new BeanCreationException(
 1219   							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
 1220   				}
 1221   			}
 1222   			original = mpvs.getPropertyValueList();
 1223   		}
 1224   		else {
 1225   			original = Arrays.asList(pvs.getPropertyValues());
 1226   		}
 1227   
 1228   		TypeConverter converter = getCustomTypeConverter();
 1229   		if (converter == null) {
 1230   			converter = bw;
 1231   		}
 1232   		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
 1233   
 1234   		// Create a deep copy, resolving any references for values.
 1235   		List deepCopy = new ArrayList(original.size());
 1236   		boolean resolveNecessary = false;
 1237   		for (Iterator it = original.iterator(); it.hasNext();) {
 1238   			PropertyValue pv = (PropertyValue) it.next();
 1239   			if (pv.isConverted()) {
 1240   				deepCopy.add(pv);
 1241   			}
 1242   			else {
 1243   				String propertyName = pv.getName();
 1244   				Object originalValue = pv.getValue();
 1245   				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
 1246   				Object convertedValue = resolvedValue;
 1247   				boolean convertible = bw.isWritableProperty(propertyName) &&
 1248   						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
 1249   				if (convertible) {
 1250   					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
 1251   				}
 1252   				// Possibly store converted value in merged bean definition,
 1253   				// in order to avoid re-conversion for every created bean instance.
 1254   				if (resolvedValue == originalValue) {
 1255   					if (convertible) {
 1256   						pv.setConvertedValue(convertedValue);
 1257   					}
 1258   					deepCopy.add(pv);
 1259   				}
 1260   				else if (originalValue instanceof TypedStringValue && convertible) {
 1261   					pv.setConvertedValue(convertedValue);
 1262   					deepCopy.add(pv);
 1263   				}
 1264   				else {
 1265   					resolveNecessary = true;
 1266   					deepCopy.add(new PropertyValue(pv, convertedValue));
 1267   				}
 1268   			}
 1269   		}
 1270   		if (mpvs != null && !resolveNecessary) {
 1271   			mpvs.setConverted();
 1272   		}
 1273   
 1274   		// Set our (possibly massaged) deep copy.
 1275   		try {
 1276   			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
 1277   		}
 1278   		catch (BeansException ex) {
 1279   			throw new BeanCreationException(
 1280   					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
 1281   		}
 1282   	}
 1283   
 1284   	/**
 1285   	 * Convert the given value for the specified target property.
 1286   	 */
 1287   	private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
 1288   		if (converter instanceof BeanWrapperImpl) {
 1289   			return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
 1290   		}
 1291   		else {
 1292   			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
 1293   			MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
 1294   			return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);
 1295   		}
 1296   	}
 1297   
 1298   
 1299   	/**
 1300   	 * Initialize the given bean instance, applying factory callbacks
 1301   	 * as well as init methods and bean post processors.
 1302   	 * <p>Called from {@link #createBean} for traditionally defined beans,
 1303   	 * and from {@link #initializeBean} for existing bean instances.
 1304   	 * @param beanName the bean name in the factory (for debugging purposes)
 1305   	 * @param bean the new bean instance we may need to initialize
 1306   	 * @param mbd the bean definition that the bean was created with
 1307   	 * (can also be <code>null</code>, if given an existing bean instance)
 1308   	 * @return the initialized bean instance (potentially wrapped)
 1309   	 * @see BeanNameAware
 1310   	 * @see BeanClassLoaderAware
 1311   	 * @see BeanFactoryAware
 1312   	 * @see #applyBeanPostProcessorsBeforeInitialization
 1313   	 * @see #invokeInitMethods
 1314   	 * @see #applyBeanPostProcessorsAfterInitialization
 1315   	 */
 1316   	protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
 1317   		if (bean instanceof BeanNameAware) {
 1318   			((BeanNameAware) bean).setBeanName(beanName);
 1319   		}
 1320   
 1321   		if (bean instanceof BeanClassLoaderAware) {
 1322   			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
 1323   		}
 1324   
 1325   		if (bean instanceof BeanFactoryAware) {
 1326   			((BeanFactoryAware) bean).setBeanFactory(this);
 1327   		}
 1328   
 1329   		Object wrappedBean = bean;
 1330   		if (mbd == null || !mbd.isSynthetic()) {
 1331   			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 1332   		}
 1333   
 1334   		try {
 1335   			invokeInitMethods(beanName, wrappedBean, mbd);
 1336   		}
 1337   		catch (Throwable ex) {
 1338   			throw new BeanCreationException(
 1339   					(mbd != null ? mbd.getResourceDescription() : null),
 1340   					beanName, "Invocation of init method failed", ex);
 1341   		}
 1342   
 1343   		if (mbd == null || !mbd.isSynthetic()) {
 1344   			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 1345   		}
 1346   		return wrappedBean;
 1347   	}
 1348   
 1349   	/**
 1350   	 * Give a bean a chance to react now all its properties are set,
 1351   	 * and a chance to know about its owning bean factory (this object).
 1352   	 * This means checking whether the bean implements InitializingBean or defines
 1353   	 * a custom init method, and invoking the necessary callback(s) if it does.
 1354   	 * @param beanName the bean name in the factory (for debugging purposes)
 1355   	 * @param bean the new bean instance we may need to initialize
 1356   	 * @param mbd the merged bean definition that the bean was created with
 1357   	 * (can also be <code>null</code>, if given an existing bean instance)
 1358   	 * @throws Throwable if thrown by init methods or by the invocation process
 1359   	 * @see #invokeCustomInitMethod
 1360   	 */
 1361   	protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
 1362   			throws Throwable {
 1363   
 1364   		boolean isInitializingBean = (bean instanceof InitializingBean);
 1365   		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
 1366   			if (logger.isDebugEnabled()) {
 1367   				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
 1368   			}
 1369   			((InitializingBean) bean).afterPropertiesSet();
 1370   		}
 1371   
 1372   		String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
 1373   		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
 1374   				!mbd.isExternallyManagedInitMethod(initMethodName)) {
 1375   			invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
 1376   		}
 1377   	}
 1378   
 1379   	/**
 1380   	 * Invoke the specified custom init method on the given bean.
 1381   	 * Called by invokeInitMethods.
 1382   	 * <p>Can be overridden in subclasses for custom resolution of init
 1383   	 * methods with arguments.
 1384   	 * @param beanName the bean name in the factory (for debugging purposes)
 1385   	 * @param bean the new bean instance we may need to initialize
 1386   	 * @param initMethodName the name of the custom init method
 1387   	 * @param enforceInitMethod indicates whether the defined init method needs to exist
 1388   	 * @see #invokeInitMethods
 1389   	 */
 1390   	protected void invokeCustomInitMethod(
 1391   			String beanName, Object bean, String initMethodName, boolean enforceInitMethod) throws Throwable {
 1392   
 1393   		Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null);
 1394   		if (initMethod == null) {
 1395   			if (enforceInitMethod) {
 1396   				throw new NoSuchMethodException("Couldn't find an init method named '" + initMethodName +
 1397   						"' on bean with name '" + beanName + "'");
 1398   			}
 1399   			else {
 1400   				if (logger.isDebugEnabled()) {
 1401   					logger.debug("No default init method named '" + initMethodName +
 1402   							"' found on bean with name '" + beanName + "'");
 1403   				}
 1404   				// Ignore non-existent default lifecycle methods.
 1405   				return;
 1406   			}
 1407   		}
 1408   
 1409   		if (logger.isDebugEnabled()) {
 1410   			logger.debug("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
 1411   		}
 1412   		ReflectionUtils.makeAccessible(initMethod);
 1413   		try {
 1414   			initMethod.invoke(bean, (Object[]) null);
 1415   		}
 1416   		catch (InvocationTargetException ex) {
 1417   			throw ex.getTargetException();
 1418   		}
 1419   	}
 1420   
 1421   
 1422   	/**
 1423   	 * Applies the <code>postProcessAfterInitialization</code> callback of all
 1424   	 * registered BeanPostProcessors, giving them a chance to post-process the
 1425   	 * object obtained from FactoryBeans (for example, to auto-proxy them).
 1426   	 * @see #applyBeanPostProcessorsAfterInitialization
 1427   	 */
 1428   	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
 1429   		return applyBeanPostProcessorsAfterInitialization(object, beanName);
 1430   	}
 1431   
 1432   	/**
 1433   	 * Overridden to clear FactoryBean instance cache as well.
 1434   	 */
 1435   	protected void removeSingleton(String beanName) {
 1436   		super.removeSingleton(beanName);
 1437   		this.factoryBeanInstanceCache.remove(beanName);
 1438   	}
 1439   
 1440   }

Save This Page
Home » spring-framework-2.5.6-with-dependencies » org.springframework » beans » factory » support » [javadoc | source]