📄 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.lang.reflect.Modifier;
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.LinkedList;
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.BeanDefinitionStoreException;
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.BeanDefinitionHolder;
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;
import org.springframework.core.CollectionFactory;
/**
* Abstract bean factory 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 <code>findMatchingBeans</code,
* 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
* @see DefaultListableBeanFactory
*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
static {
// Eagerly load the DisposableBean and DestructionAwareBeanPostProcessor
// classes to avoid weird classloader issues on application shutdown in
// WebLogic 8.1. (Reported by Andreas Senft and Eric Ma.)
DisposableBean.class.getName();
DestructionAwareBeanPostProcessor.class.getName();
}
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
/**
* Set that holds all inner beans created by this factory that implement
* the DisposableBean interface, to be destroyed on destroySingletons.
* @see #destroySingletons
*/
private final Map disposableInnerBeans = Collections.synchronizedMap(new HashMap());
private final Map dependentBeanMap = Collections.synchronizedMap(new HashMap());
/**
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
}
/**
* Create a new AbstractAutowireCapableBeanFactory with the given parent.
* @param parentBeanFactory parent bean factory, or null if none
*/
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
super(parentBeanFactory);
}
/**
* Set the instantiation strategy to use.
* Can be called by subclasses during initialization.
* Default is CglibSubclassingInstantiationStrategy.
* @see CglibSubclassingInstantiationStrategy
*/
protected void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
//---------------------------------------------------------------------
// 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 = instantiationStrategy.instantiate(bd, null, this);
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 void applyBeanPropertyValues(Object existingBean, String name) throws BeansException {
RootBeanDefinition bd = getMergedBeanDefinition(name, true);
applyPropertyValues(name, bd, new BeanWrapperImpl(existingBean), bd.getPropertyValues());
}
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(
"postProcessAfterInitialization method of BeanPostProcessor [" + beanProcessor +
"] returned null for bean [" + result + "] with name [" + name + "]");
}
}
return result;
}
//---------------------------------------------------------------------
// Implementation of superclass abstract methods
//---------------------------------------------------------------------
/**
* Delegates to full createBean version with allowEagerCaching=true.
* @see #createBean(String, RootBeanDefinition, Object[], boolean)
*/
protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args)
throws BeansException {
return createBean(beanName, mergedBeanDefinition, args, true);
}
/**
* Create a bean instance for the given bean definition.
* @param beanName name of the bean
* @param mergedBeanDefinition the bean definition for the bean
* @param allowEagerCaching whether eager caching of singletons is allowed
* (typically true for normal beans, but false for inner beans)
* @param args arguments to use if this is a prototype constructed by a factory method.
* In this case, this will override any args specified in the bean definitions.
* This parameter should be null otherwise.
* @return a new instance of the bean
* @throws BeansException in case of errors
*/
protected Object createBean(
String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args, boolean allowEagerCaching)
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;
Object bean = null;
String errorMessage = null;
boolean eagerlyCached = false;
try {
// instantiate 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 {
// use no-arg constructor
Object beanInstance = this.instantiationStrategy.instantiate(mergedBeanDefinition, beanName, this);
instanceWrapper = new BeanWrapperImpl(beanInstance);
initBeanWrapper(instanceWrapper);
}
bean = instanceWrapper.getWrappedInstance();
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
if (allowEagerCaching && mergedBeanDefinition.isSingleton()) {
addSingleton(beanName, bean);
eagerlyCached = true;
}
// initialize bean
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);
}
bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
invokeInitMethods(beanName, mergedBeanDefinition, bean);
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
catch (BeanCreationException ex) {
if (eagerlyCached) {
removeSingleton(beanName);
}
throw ex;
}
catch (Throwable ex) {
if (eagerlyCached) {
removeSingleton(beanName);
}
throw new BeanCreationException(
mergedBeanDefinition.getResourceDescription(), beanName, errorMessage, ex);
}
// Register bean as dependent on specified "dependsOn" beans.
// This information is used on shutdown, to destroy dependent beans
// before the beans that they depend on.
if (mergedBeanDefinition.isSingleton()) {
String[] dependsOn = mergedBeanDefinition.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
registerDependentBean(dependsOn[i], beanName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -