⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractautowirecapablebeanfactory.java

📁 Java/J2EE application framework based on [Expert One-on-One J2EE Design and Development] by Rod John
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * 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 + -