📄 abstractautowirecapablebeanfactory.java
字号:
/*
* Copyright 2002-2007 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.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.FatalBeanException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorUtils;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
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.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
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.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Abstract bean factory superclass that implements default bean creation,
* with the full capabilities specified by the {@link RootBeanDefinition} class.
* Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
* interface in addition to AbstractBeanFactory's {@link #createBean} method.
*
* <p>Provides bean creation (with constructor resolution), property population,
* wiring (including autowiring), and initialization. Handles runtime bean
* references, resolves managed collections, calls initialization methods, etc.
* Supports autowiring constructors, properties by name, and properties by type.
*
* <p>The main template method to be implemented by subclasses is
* {@link #findAutowireCandidates}, used for autowiring by type. In case of
* a factory which is capable of searching its bean definitions, matching
* beans will typically be implemented through such a search. For other
* factory styles, simplified matching algorithms can be implemented.
*
* <p>Note that this class does <i>not</i> assume or implement bean definition
* registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
* of the {@link org.springframework.beans.factory.ListableBeanFactory} and
* {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
* view of such a factory, respectively.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rob Harrop
* @since 13.02.2004
* @see RootBeanDefinition
* @see DefaultListableBeanFactory
* @see BeanDefinitionRegistry
*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
/** Whether to automatically try to resolve circular references between beans */
private boolean allowCircularReferences = true;
/**
* Whether to resort to injecting a raw bean instance in case of circular reference,
* even if the injected bean eventually got wrapped.
*/
private boolean allowRawInjectionDespiteWrapping = false;
/**
* Dependency types to ignore on dependency check and autowire, as Set of
* Class objects: for example, String. Default is none.
*/
private final Set ignoredDependencyTypes = new HashSet();
/**
* Dependency interfaces to ignore on dependency check and autowire, as Set of
* Class objects. By default, only the BeanFactory interface is ignored.
*/
private final Set ignoredDependencyInterfaces = new HashSet();
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
private final Map factoryBeanInstanceCache = new HashMap();
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
private final Map filteredPropertyDescriptorsCache = new HashMap();
/**
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
/**
* Create a new AbstractAutowireCapableBeanFactory with the given parent.
* @param parentBeanFactory parent bean factory, or <code>null</code> if none
*/
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}
/**
* Set the instantiation strategy to use for creating bean instances.
* Default is CglibSubclassingInstantiationStrategy.
* @see CglibSubclassingInstantiationStrategy
*/
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
/**
* Return the instantiation strategy to use for creating bean instances.
*/
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
/**
* Set whether to allow circular references between beans - and automatically
* try to resolve them.
* <p>Note that circular reference resolution means that one of the involved beans
* will receive a reference to another bean that is not fully initialized yet.
* This can lead to subtle and not-so-subtle side effects on initialization;
* it does work fine for many scenarios, though.
* <p>Default is "true". Turn this off to throw an exception when encountering
* a circular reference, disallowing them completely.
* <p><b>NOTE:</b> It is generally recommended to not rely on circular references
* between your beans. Refactor your application logic to have the two beans
* involved delegate to a third bean that encapsulates their common logic.
*/
public void setAllowCircularReferences(boolean allowCircularReferences) {
this.allowCircularReferences = allowCircularReferences;
}
/**
* Set whether to allow the raw injection of a bean instance into some other
* bean's property, despite the injected bean eventually getting wrapped
* (for example, through AOP auto-proxying).
* <p>This will only be used as a last resort in case of a circular reference
* that cannot be resolved otherwise: essentially, preferring a raw instance
* getting injected over a failure of the entire bean wiring process.
* <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped
* raw beans injected into some of your references, which was Spring 1.2's
* (arguably unclean) default behavior.
* <p><b>NOTE:</b> It is generally recommended to not rely on circular references
* between your beans, in particular with auto-proxying involved.
* @see #setAllowCircularReferences
*/
public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) {
this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
}
/**
* Ignore the given dependency type for autowiring:
* for example, String. Default is none.
*/
public void ignoreDependencyType(Class type) {
this.ignoredDependencyTypes.add(type);
}
/**
* Ignore the given dependency interface for autowiring.
* <p>This will typically be used by application contexts to register
* dependencies that are resolved in other ways, like BeanFactory through
* BeanFactoryAware or ApplicationContext through ApplicationContextAware.
* <p>By default, only the BeanFactoryAware interface is ignored.
* For further types to ignore, invoke this method for each type.
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.ApplicationContextAware
*/
public void ignoreDependencyInterface(Class ifc) {
this.ignoredDependencyInterfaces.add(ifc);
}
public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
super.copyConfigurationFrom(otherFactory);
if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
AbstractAutowireCapableBeanFactory otherAutowireFactory =
(AbstractAutowireCapableBeanFactory) otherFactory;
this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
}
}
//---------------------------------------------------------------------
// Implementation of AutowireCapableBeanFactory interface
//---------------------------------------------------------------------
public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck)
throws BeansException {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
return createBean(beanClass.getName(), bd, null);
}
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck)
throws BeansException {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanClass.getName(), bd, null).getWrappedInstance();
}
else {
Object bean = getInstantiationStrategy().instantiate(bd, null, this);
populateBean(beanClass.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");
}
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(existingBean.getClass(), autowireMode, dependencyCheck);
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
populateBean(existingBean.getClass().getName(), bd, new BeanWrapperImpl(existingBean));
}
public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
RootBeanDefinition bd = getMergedBeanDefinition(beanName, true);
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
}
public Object configureBean(Object existingBean, String beanName) throws BeansException {
RootBeanDefinition bd = getMergedBeanDefinition(beanName, true);
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
populateBean(beanName, bd, bw);
return initializeBean(beanName, existingBean, bd);
}
public Object initializeBean(Object existingBean, String beanName) {
return initializeBean(beanName, existingBean, null);
}
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessAfterInitialization(result, 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
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -