Spring源码IOC之实例化Bean的方式

2.4 doCreateBean 概览

经过了前面的一系列准备,接下来进入IOC的核心方法doCreateBean。中间涉及较多的知识点,分多个小节分析,下面先来了解一下doCreateBean的主要逻辑。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {
	// Instantiate the bean.
	// 实例化bean。
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	// Allow post-processors to modify the merged bean definition.
	// 允许后处理器修改合并的bean定义。
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}
	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	// 主动缓存单例,以便能够解析循环引用,即使是在BeanFactoryAware等生命周期接口触发的情况下。
	boolean earlySingletonExposure = (mbd.isSingleton()
			&& this.allowCircularReferences
			&& isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	// Initialize the bean instance.
	// 初始化bean实例。
	Object exposedObject = bean;
	try {
		populateBean(beanName, mbd, instanceWrapper);
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}
	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. 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 " +
							"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}
	// Register bean as disposable.
	// 将单例bean注册到disposableBeans(LinkedHashMap)中,以方面容器关闭时回调对应bean的销毁方法
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}
	return exposedObject;
}

主要逻辑:

  • 实例化bean
  • 允许后处理器修改合并的bean定义
  • 主动缓存单例,以便能够解析循环引用
  • 初始化bean实例
  • 异常处理
  • 将单例bean注册到disposableBeans(LinkedHashMap)中,以方面容器关闭时回调对应bean的销毁方法
  • 返回bean的实例
2.4 实例化bean
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
	// 确保bean类在此时已经被解析。
	Class<?> beanClass = resolveBeanClass(mbd, beanName);
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	}
	// Supplier 实例化
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}
	// 工厂方法 实例化
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}
	// Shortcut when re-creating the same bean...
	// 创建相同bean时,保存解析快照
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			return instantiateBean(beanName, mbd);
		}
	}
	// Candidate constructors for autowiring?
	// 查找候选构造函数,并尝试使用有参构造函数实例化
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null
			|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR
			|| mbd.hasConstructorArgumentValues()
			|| !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}
	// Preferred constructors for default construction?
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}
	// No special handling: simply use no-arg constructor.
	// 无参构造函数实例化。
	return instantiateBean(beanName, mbd);
}

实例化bean的方式:

  • Supplier
  • 工厂方法:
    • 静态工厂
    • 实例工厂
  • 构造函数:
    • 有参构造函数
    • 无参构造函数
  • 快照实例化,该方式有些特殊。例如针对某个单例bean,创建完之后销毁,Spring依然会保留其解析快照,节约下次解析开销
2.4.1 Supplier

Supplier 接口是一个函数式接口,下面演示一下使用方式:

@Test
public void SupplierTest() {
	AnnotationConfigApplicationContext context =
			new AnnotationConfigApplicationContext("org/springframework/demo/demo.xml");
	context.registerBean("dog", Dog.class, new Supplier<Dog>() {
		@Override
		public Dog get() {
			return new Dog();
		}
	});
	context.getBean("dog", Dog.class).sayHello();
}

再来看一下Supplier接口的定义:

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

通过get方法返回bean的实例。这种实例化方式源码很简单,不多赘述。

2.4.2 静态工厂

该方式源码比较简单,只演示一下其使用方式:

package org.springframework.demo.factory;

import org.springframework.demo.Dog;

public class DogStaticFactory {

	// 静态工厂方法
	public static Dog newInstance(String name, int age) {
		// 返回需要的Bean实例
		return new Dog(name, age);
	}
}

<!-- 静态工厂方法实例化 -->
<bean id="dog" class="org.springframework.demo.factory.DogStaticFactory" factory-method="newInstance">
	<!-- 指定构造器参数 index对应构造器中参数的位置 -->
	<constructor-arg index="0" value="小明"/>
	<constructor-arg index="1" value="3"/>
</bean>
2.4.3 实例工厂

该方式源码比较简单,只演示一下其使用方式:

package org.springframework.demo.factory;

import org.springframework.demo.Dog;

public class DogFactory {

	public Dog newInstance(String name, int age) {
		return new Dog(name, age);
	}
}

<!-- 实例工厂方法实例化 -->
<bean id="dogFactory" class="org.springframework.demo.factory.DogFactory"/>
<!-- 不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法 -->
<bean id="dog" factory-bean="dogFactory" factory-method="newInstance">
	<constructor-arg index="0" value="小明"/>
	<constructor-arg index="1" value="3"/>
</bean>
2.4.4 有参构造函数

先来看一下使用有参构造函数的条件:

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null
		|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR
		|| mbd.hasConstructorArgumentValues()
		|| !ObjectUtils.isEmpty(args)) {
	return autowireConstructor(beanName, mbd, ctors, args);
}
  • determineConstructorsFromBeanPostProcessors 解析的构造函数不为空
  • mbd.getResolvedAutowireMode 解析自动装配类型为构造函数
  • mbd.hasConstructorArgumentValues 通过配置文件指定了构造函数参数
  • !ObjectUtils.isEmpty(args) 获取bean的时候显示指定了构造函数参数
2.4.5 无参构造函数
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged(
					(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
					getAccessControlContext());
		}
		else {
			// 获取实例化策略,并实例化bean
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲来也无事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值