📄 abstractautowirecapablebeanfactory.java
字号:
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.RuntimeBeanReference;
/**
* Abstract BeanFactory superclass that implements default bean creation.
* Implements the AutowireCapableBeanFactory interface.
*
* <p>Provides bean creation, initialization and wiring, supporting
* autowiring and constructor resolution. Handles runtime bean references,
* managed collections, and bean destruction.
*
* <p>The main template method to be implemented by subclasses is
* findMatchingBeans, used for autowiring by type. Note that this class
* does <i>not</i> implement bean definition registry capabilities
* (DefaultListableBeanFactory does).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 13.02.2004
* @see #findMatchingBeans
*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
static {
// Eagerly load the DisposableBean class to avoid weird classloader
// issues on EJB shutdown within WebLogic 8.1's EJB container.
// (Reported by Andreas Senft.)
DisposableBean.class.getName();
}
/**
* Set that holds all inner beans created by this factory that implement
* the DisposableBean interface, to be destroyed on destroySingletons.
* @see #destroySingletons
*/
private final Set disposableInnerBeans = Collections.synchronizedSet(new HashSet());
public AbstractAutowireCapableBeanFactory() {
}
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
super(parentBeanFactory);
}
//---------------------------------------------------------------------
// Implementation of AutowireCapableBeanFactory
//---------------------------------------------------------------------
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck)
throws BeansException {
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanClass.getName(), bd).getWrappedInstance();
}
else {
Object bean = BeanUtils.instantiateClass(beanClass);
populateBean(bean.getClass().getName(), bd, new BeanWrapperImpl(bean));
return bean;
}
}
public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException {
if (autowireMode != AUTOWIRE_BY_NAME && autowireMode != AUTOWIRE_BY_TYPE) {
throw new IllegalArgumentException("Just constants AUTOWIRE_BY_NAME and AUTOWIRE_BY_TYPE allowed");
}
RootBeanDefinition bd = new RootBeanDefinition(existingBean.getClass(), autowireMode, dependencyCheck);
populateBean(existingBean.getClass().getName(), bd, new BeanWrapperImpl(existingBean));
}
public Object applyBeanPostProcessorsBeforeInitialization(Object bean, String name) throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Invoking BeanPostProcessors before initialization of bean '" + name + "'");
}
Object result = bean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessBeforeInitialization(result, name);
if (result == null) {
throw new BeanCreationException("postProcessBeforeInitialization method of BeanPostProcessor [" +
beanProcessor + "] returned null for bean [" + result +
"] with name [" + name + "]");
}
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object bean, String name) throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Invoking BeanPostProcessors after initialization of bean '" + name + "'");
}
Object result = bean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessAfterInitialization(result, name);
if (result == null) {
throw new BeanCreationException("postProcessAfter" +
"Initialization method of BeanPostProcessor [" +
beanProcessor + "] returned null for bean [" + result +
"] with name [" + name + "]");
}
}
return result;
}
//---------------------------------------------------------------------
// Implementation of superclass abstract methods
//---------------------------------------------------------------------
protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition) throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "' with merged definition [" + mergedBeanDefinition + "]");
}
if (mergedBeanDefinition.getDependsOn() != null) {
for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
// guarantee initialization of beans that the current one depends on
getBean(mergedBeanDefinition.getDependsOn()[i]);
}
}
BeanWrapper instanceWrapper = null;
if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mergedBeanDefinition.hasConstructorArgumentValues()) {
instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
}
else {
instanceWrapper = new BeanWrapperImpl(mergedBeanDefinition.getBeanClass());
initBeanWrapper(instanceWrapper);
}
Object bean = instanceWrapper.getWrappedInstance();
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
if (mergedBeanDefinition.isSingleton()) {
addSingleton(beanName, bean);
}
populateBean(beanName, mergedBeanDefinition, instanceWrapper);
try {
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);
}
bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
invokeInitMethods(beanName, mergedBeanDefinition, bean);
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Exception ex) {
throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
"Initialization of bean failed", ex);
}
return bean;
}
/**
* "autowire constructor" (with constructor arguments by type) behaviour.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName name of the bean to autowire by type
* @param mergedBeanDefinition bean definition to update through autowiring
* @return BeanWrapper for the new instance
*/
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mergedBeanDefinition)
throws BeansException {
ConstructorArgumentValues cargs = mergedBeanDefinition.getConstructorArgumentValues();
ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues();
int minNrOfArgs = 0;
if (cargs != null) {
minNrOfArgs = cargs.getNrOfArguments();
for (Iterator it = cargs.getIndexedArgumentValues().entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int index = ((Integer) entry.getKey()).intValue();
if (index < 0) {
throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
"Invalid constructor argument index: " + index);
}
if (index > minNrOfArgs) {
minNrOfArgs = index + 1;
}
String argName = "constructor argument with index " + index;
ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder) entry.getValue();
Object resolvedValue = resolveValueIfNecessary(beanName, mergedBeanDefinition, argName, valueHolder.getValue());
resolvedValues.addIndexedArgumentValue(index, resolvedValue, valueHolder.getType());
}
for (Iterator it = cargs.getGenericArgumentValues().iterator(); it.hasNext();) {
ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder) it.next();
String argName = "constructor argument";
Object resolvedValue = resolveValueIfNecessary(beanName, mergedBeanDefinition, argName, valueHolder.getValue());
resolvedValues.addGenericArgumentValue(resolvedValue, valueHolder.getType());
}
}
Constructor[] constructors = mergedBeanDefinition.getBeanClass().getConstructors();
Arrays.sort(constructors, new Comparator() {
public int compare(Object o1, Object o2) {
int c1pl = ((Constructor) o1).getParameterTypes().length;
int c2pl = ((Constructor) o2).getParameterTypes().length;
return (new Integer(c1pl)).compareTo(new Integer(c2pl)) * -1;
}
});
BeanWrapperImpl bw = new BeanWrapperImpl();
initBeanWrapper(bw);
Constructor constructorToUse = null;
Object[] argsToUse = null;
int minTypeDiffWeight = Integer.MAX_VALUE;
for (int i = 0; i < constructors.length; i++) {
try {
Constructor constructor = constructors[i];
if (constructor.getParameterTypes().length < minNrOfArgs) {
throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
minNrOfArgs + " constructor arguments specified but no matching constructor found in bean '" +
beanName + "' (hint: specify index arguments for simple parameters to avoid type ambiguities)");
}
Class[] argTypes = constructor.getParameterTypes();
Object[] args = new Object[argTypes.length];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -