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

📄 abstractautowirecapablebeanfactory.java

📁 spring api 源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
			throws BeanCreationException {

		// Guarantee initialization of beans that the current one depends on.
		String[] dependsOn = mbd.getDependsOn();
		if (dependsOn != null) {
			for (int i = 0; i < dependsOn.length; i++) {
				getBean(dependsOn[i]);
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "' with merged definition [" + mbd + "]");
		}

		// Make sure bean class is actually resolved at this point.
		Class beanClass = resolveBeanClass(mbd, beanName);

		// Prepare method overrides.
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		String errorMessage = null;

		try {
			// Instantiate the bean.
			errorMessage = "BeanPostProcessor before instantiation of bean failed";

			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			if (beanClass != null &&
					!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					return bean;
				}
			}

			// Instantiate the bean.
			errorMessage = "Instantiation of bean failed";

			BeanWrapper instanceWrapper = null;
			if (mbd.isSingleton()) {
				synchronized (getSingletonMutex()) {
					instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
				}
			}

			if (instanceWrapper == null) {
				instanceWrapper = createBeanInstance(beanName, mbd, args);
			}
			Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

			// Eagerly cache singletons to be able to resolve circular references
			// even when triggered by lifecycle interfaces like BeanFactoryAware.
			if (mbd.isSingleton() && this.allowCircularReferences &&
					isSingletonCurrentlyInCreation(beanName)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Eagerly caching bean '" + beanName +
							"' to allow for resolving potential circular references");
				}
				addSingleton(beanName, bean);
			}

			// Initialize the bean instance.
			errorMessage = "Initialization of bean failed";

			// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
			// state of the bean before properties are set. This can be used, for example,
			// to support styles of field injection.
			boolean continueWithPropertyPopulation = true;

			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
					BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
					if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
						if (!ibp.postProcessAfterInstantiation(bean, beanName)) {
							continueWithPropertyPopulation = false;
							break;
						}
					}
				}
			}

			if (continueWithPropertyPopulation) {
				populateBean(beanName, mbd, instanceWrapper);
			}

			Object originalBean = bean;
			bean = initializeBean(beanName, bean, mbd);

			if (!this.allowRawInjectionDespiteWrapping && originalBean != bean &&
					mbd.isSingleton() && hasDependentBean(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName,
						"Bean with name '" + beanName + "' has been injected into other beans " +
						getDependentBeans(beanName) + " in its raw version as part of a circular reference, " +
						"but has eventually been wrapped (for example as part of auto-proxy creation). " +
						"This means that said other beans do not use the final version of the bean. " +
						"This is often the result of over-eager type matching - consider using " +
						"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
			}

			// Register bean as disposable, and also as dependent on specified "dependsOn" beans.
			registerDisposableBeanIfNecessary(beanName, originalBean, mbd);

			return bean;
		}

		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, errorMessage, ex);
			}
		}
	}

	/**
	 * Predict the eventual bean type for the given bean.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition to determine the type for
	 * @return the type of the bean, or <code>null</code> if not predictable
	 */
	protected Class predictBeanType(String beanName, RootBeanDefinition mbd) {
		Class beanClass = null;
		if (mbd.getFactoryMethodName() != null) {
			beanClass = getTypeForFactoryMethod(beanName, mbd);
		}
		else {
			beanClass = resolveBeanClass(mbd, beanName);
		}
		// Apply SmartInstantiationAwareBeanPostProcessors to predict the
		// eventual type after a before-instantiation shortcut.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
				BeanPostProcessor bp = (BeanPostProcessor) it.next();
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Class processedType = ibp.predictBeanType(beanClass, beanName);
					if (processedType != null) {
						return processedType;
					}
				}
			}
		}
		return beanClass;
	}

	/**
	 * Determine the bean type for the given bean definition which is based on
	 * a factory method. Only called if there is no singleton instance registered
	 * for the target bean already.
	 * <p>This implementation determines the type matching {@link #createBean}'s
	 * different creation strategies. As far as possible, we'll perform static
	 * type checking to avoid creation of the target bean.
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @return the type for the bean if determinable, or <code>null</code> else
	 * @see #createBean
	 */
	protected Class getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd) {
		Class factoryClass = null;
		boolean isStatic = true;

		String factoryBeanName = mbd.getFactoryBeanName();
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			// Check declared factory method return type on factory class.
			factoryClass = getType(factoryBeanName);
			isStatic = false;
		}
		else {
			// Check declared factory method return type on bean class.
			factoryClass = resolveBeanClass(mbd, beanName);
		}

		if (factoryClass == null) {
			return null;
		}

		// 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 = mbd.getConstructorArgumentValues().getArgumentCount();
		Method[] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass);
		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(mbd.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;
		}
	}

	/**
	 * This implementation checks the FactoryBean's <code>getObjectType</code> method
	 * on a plain instance of the FactoryBean, without bean properties applied yet.
	 * If this doesn't return a type yet, a full creation of the FactoryBean is
	 * used as fallback (through delegation to the superclass's implementation).
	 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
	 * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
	 * it will be fully created to check the type of its exposed object.
	 */
	protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
		FactoryBean fb = (mbd.isSingleton() ?
				getSingletonFactoryBeanForTypeCheck(beanName, mbd) :
				getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));

		if (fb != null) {
			// Try to obtain the FactoryBean's object type from this early stage of the instance.
			Class objectType = getTypeForFactoryBean(fb);
			if (objectType != null) {
				return objectType;
			}
		}

		// No type found - fall back to full creation of the FactoryBean instance.
		return super.getTypeForFactoryBean(beanName, mbd);
	}


	//---------------------------------------------------------------------
	// Implementation methods
	//---------------------------------------------------------------------

	/**
	 * Obtain a "shortcut" singleton FactoryBean instance to use for a
	 * <code>getObjectType()</code> call, without full initialization
	 * of the FactoryBean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the FactoryBean instance, or <code>null</code> to indicate
	 * that we couldn't obtain a shortcut FactoryBean instance
	 */
	private FactoryBean getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
		synchronized (getSingletonMutex()) {
			BeanWrapper bw = (BeanWrapper) this.factoryBeanInstanceCache.get(beanName);
			if (bw != null) {
				return (FactoryBean) bw.getWrappedInstance();
			}
			if (isSingletonCurrentlyInCreation(beanName)) {
				return null;
			}
			Object instance = null;
			try {
				// Mark this bean as currently in creation, even if just partially.
				beforeSingletonCreation(beanName);
				// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
				Class beanClass = resolveBeanClass(mbd, beanName);
				if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
					Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName);
					if (bean != null) {
						instance = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
				if (instance == null) {
					bw = createBeanInstance(beanName, mbd, null);
					instance = bw.getWrappedInstance();
				}
			}
			finally {
				// Finished partial creation of this bean.
				afterSingletonCreation(beanName);
			}
			if (!(instance instanceof FactoryBean)) {
				throw new BeanCreationException(beanName,
						"Bean instance of type [" + instance.getClass() + "] is not a FactoryBean");
			}
			if (bw != null) {
				this.factoryBeanInstanceCache.put(beanName, bw);
			}
			return (FactoryBean) instance;
		}
	}

	/**
	 * Obtain a "shortcut" non-singleton FactoryBean instance to use for a
	 * <code>getObjectType()</code> call, without full initialization
	 * of the FactoryBean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the FactoryBean instance, or <code>null</code> to indicate
	 * that we couldn't obtain a shortcut FactoryBean instance
	 */
	private FactoryBean getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
		if (isPrototypeCurrentlyInCreation(beanName)) {
			return null;
		}
		Object instance = null;
		try {
			// Mark this bean as currently in creation, even if just partially.
			beforePrototypeCreation(beanName);
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Class beanClass = resolveBeanClass(mbd, beanName);
			if (beanClass != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName);
				if (bean != null) {
					instance = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
			if (instance == null) {
				BeanWrapper bw = createBeanInstance(beanName, mbd, null);
				instance = bw.getWrappedInstance();
			}
		}
		finally {
			// Finished partial creation of this bean.
			afterPrototypeCreation(beanName);
		}
		if (!(instance instanceof FactoryBean)) {
			throw new BeanCreationException(beanName,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -