/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object createBean(String beanName,
RootBeanDefinition mergedBeanDefinition,
Object[] args ) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName +
"' with merged definition [" + mergedBeanDefinition + "]");
}
Object bean = null;
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
if (mergedBeanDefinition.hasBeanClass()) {
bean = applyBeanPostProcessorsBeforeInstantiation(mergedBeanDefinition.getBeanClass(), beanName);
if (bean != null) {
return bean;
}
}
// Guarantee initialization of beans that the current one depends on.
if (mergedBeanDefinition.getDependsOn() != null) {
for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
getBean(mergedBeanDefinition.getDependsOn()[i]);
}
}
BeanWrapper instanceWrapper = null;
Object originalBean = null;
String errorMessage = null;
try {
// Instantiate the bean.
errorMessage = "Instantiation of bean failed";
if (mergedBeanDefinition.getFactoryMethodName() != null) {
instanceWrapper = instantiateUsingFactoryMethod(beanName, mergedBeanDefinition, args);
}
else if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mergedBeanDefinition.hasConstructorArgumentValues() ) {
instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
}
else {
// No special handling: simply use no-arg constructor.
instanceWrapper = instantiateBean(beanName, mergedBeanDefinition);
}
bean = instanceWrapper.getWrappedInstance();
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
if (isAllowCircularReferences() && isSingletonCurrentlyInCreation(beanName)) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean with name '" + beanName +
"' to allow for resolving potential circular references");
}
addSingleton(beanName, bean);
}
// Initialize the bean instance.
errorMessage = "Initialization of bean failed";
populateBean(beanName, mergedBeanDefinition, instanceWrapper);
if (bean instanceof BeanNameAware) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking setBeanName on BeanNameAware bean '" + beanName + "'");
}
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanFactoryAware) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking setBeanFactory on BeanFactoryAware bean '" + beanName + "'");
}
((BeanFactoryAware) bean).setBeanFactory(this);
}
originalBean = bean;
bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
invokeInitMethods(beanName, bean, mergedBeanDefinition);
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mergedBeanDefinition.getResourceDescription(), beanName, errorMessage, ex);
}
// Register bean as disposable, and also as dependent on specified "dependsOn" beans.
registerDisposableBeanIfNecessary(beanName, originalBean, mergedBeanDefinition);
return bean;
}