📄 abstractautowirecapablebeanfactory.java
字号:
"postProcessAfterInitialization method of BeanPostProcessor [" + beanProcessor +
"] returned null for bean [" + result + "] with name [" + beanName + "]");
}
}
return result;
}
//---------------------------------------------------------------------
// Implementation of relevant AbstractBeanFactory template methods
//---------------------------------------------------------------------
/**
* 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;
}
/**
* This implementation determines the type matching <code>createBean</code>'s
* different creation strategies.
* <p>As far as possible, we'll perform static type checking to avoid creation
* of the target bean. However, in case of a non-lazy-init singleton with a
* "factory-bean" reference, checking the actual return type is preferable:
* For example, a generic service factory might be declared with return type
* "Object" or a generic service marker interface, where static type checking
* wouldn't reveal any actual type.
*/
protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mergedBeanDefinition) {
// Create bean in case of "factory-bean" declaration, to find out actual type.
// Essentially, this is treated like an implementation of the FactoryBean interface.
// If not a singleton or marked as lazy-init, we'll resort to static type checking.
if (mergedBeanDefinition.getFactoryBeanName() != null &&
mergedBeanDefinition.isSingleton() && !mergedBeanDefinition.isLazyInit()) {
return getBean(beanName).getClass();
}
Class factoryClass = null;
boolean isStatic = true;
if (mergedBeanDefinition.getFactoryBeanName() != null) {
// Check declared factory method return type on factory class.
factoryClass = getType(mergedBeanDefinition.getFactoryBeanName());
isStatic = false;
}
else {
// Check declared factory method return type on bean class.
if (!mergedBeanDefinition.hasBeanClass()) {
return null;
}
factoryClass = mergedBeanDefinition.getBeanClass();
}
// If all factory methods have the same return type, return that type.
// Can't clearly figure out exact method due to type converting / autowiring!
int minNrOfArgs = mergedBeanDefinition.getConstructorArgumentValues().getArgumentCount();
Method[] candidates = factoryClass.getMethods();
Set returnTypes = new HashSet(1);
for (int i = 0; i < candidates.length; i++) {
Method factoryMethod = candidates[i];
if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic &&
factoryMethod.getName().equals(mergedBeanDefinition.getFactoryMethodName()) &&
factoryMethod.getParameterTypes().length >= minNrOfArgs) {
returnTypes.add(factoryMethod.getReturnType());
}
}
if (returnTypes.size() == 1) {
// Clear return type found: all factory methods return same type.
return (Class) returnTypes.iterator().next();
}
else {
// Ambiguous return types found: return null to indicate "not determinable".
return null;
}
}
//---------------------------------------------------------------------
// Implementation methods
//---------------------------------------------------------------------
/**
* Instantiate the given bean using its default constructor.
* @param beanName name of the bean
* @param mergedBeanDefinition the bean definition for the bean
* @return BeanWrapper for the new instance
*/
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mergedBeanDefinition)
throws BeansException {
Object beanInstance = getInstantiationStrategy().instantiate(mergedBeanDefinition, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
/**
* Instantiate the bean using a named factory method. The method may be static, if the
* mergedBeanDefinition parameter specifies a class, rather than a factoryBean, or
* an instance variable on a factory object itself configured using Dependency Injection.
* <p>Implementation requires iterating over the static or instance methods with the
* name specified in the RootBeanDefinition (the method may be overloaded) and trying
* to match with the parameters. We don't have the types attached to constructor args,
* so trial and error is the only way to go here. The explicitArgs array may contain
* argument values passed in programmatically via the corresponding getBean method.
* @param beanName name of the bean
* @param mergedBeanDefinition the bean definition for the bean
* @param explicitArgs argument values passed in programmatically via the getBean
* method, or <code>null</code> if none (-> use constructor argument values from bean definition)
* @return BeanWrapper for the new instance
* @see #getBean(String, Object[])
*/
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mergedBeanDefinition, Object[] explicitArgs) throws BeansException {
ConstructorArgumentValues cargs = mergedBeanDefinition.getConstructorArgumentValues();
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs = 0;
if (explicitArgs == null) {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mergedBeanDefinition, cargs, resolvedValues);
}
else {
minNrOfArgs = explicitArgs.length;
}
boolean isStatic = true;
Class factoryClass = null;
Object factoryBean = null;
if (mergedBeanDefinition.getFactoryBeanName() != null) {
factoryBean = getBean(mergedBeanDefinition.getFactoryBeanName());
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
// It's a static factory method on the bean class.
factoryClass = mergedBeanDefinition.getBeanClass();
}
BeanWrapperImpl bw = new BeanWrapperImpl();
initBeanWrapper(bw);
// Try all methods with this name to see if they match the given arguments.
Method[] candidates = factoryClass.getMethods();
Method factoryMethodToUse = null;
Object[] argsToUse = null;
int minTypeDiffWeight = Integer.MAX_VALUE;
for (int i = 0; i < candidates.length; i++) {
Method factoryMethod = candidates[i];
if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic &&
factoryMethod.getName().equals(mergedBeanDefinition.getFactoryMethodName()) &&
factoryMethod.getParameterTypes().length >= minNrOfArgs) {
Class[] argTypes = factoryMethod.getParameterTypes();
ArgumentsHolder args = null;
if (resolvedValues != null) {
// Resolved contructor arguments: type conversion and/or autowiring necessary.
try {
args = createArgumentArray(
beanName, mergedBeanDefinition, resolvedValues, bw, argTypes, "factory method");
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring factory method [" + factoryMethod + "] of bean '" + beanName +
"': " + ex.getMessage());
}
if (i == candidates.length - 1 && factoryMethodToUse == null) {
throw ex;
}
else {
// Swallow and try next overloaded factory method.
continue;
}
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (argTypes.length != explicitArgs.length) {
continue;
}
args = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = args.getTypeDifferenceWeight(argTypes);
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = factoryMethod;
argsToUse = args.arguments;
minTypeDiffWeight = typeDiffWeight;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -