protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.// 通过BeanDefinition解析出要创建的对象的Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 这里判断BeanDefinition只是指定了ClassName 将解析到的Class对象设置进去,以供下面实例化时直接使用if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
thrownew BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// 通过实现通过BeanPostProcessor的子接口定义的InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation// 来获取目标对象(如果BeanDefinition允许的话。),如果获取实例成功则调用beanProcessor.postProcessAfterInitialization(result, beanName)// 完成实例化回调
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
thrownew BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 这里实现,通过构造器、工厂方法、Supplier、等实例化对象,下面查看细节
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...throw ex;
}
catch (Throwable ex) {
thrownew BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
doCreateBean(beanName, mbdToUse, args);方法的实现细节
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//通过有参、无参构造器或者工厂方法来创建对象,并使用BeanWrapper进行包装创建出来的对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 这里调用BeanPostProcessors中类型为MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition的回调
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
thrownew 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.// 这里只是实例化了当前对象,下面在populate属性时,可能会涉及到依赖当前对象的实例创建,而当前对象尚未初始化完毕// 为了能满足被后续对象的创建,这里将当前对象的引用暴露给SingletonBeanRegistryboolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.// 执行对象初始化。(init)
Object exposedObject = bean;
try {
// 这里进行属性注入(setter注入)、以及进行回调用来依赖检查注入BeanPostProcessor.postProcessPropertyValues(..)//(其中@Autowired 以及@Resource等注解是基于BeanPostProcessor系列回调实现的)
populateBean(beanName, mbd, instanceWrapper);
//这里进行BeanNameAware、BeanClassLoaderAware、BeanFactoryAware//以及执行对象 init方法//并实现BeanPostProcessor.postProcessBeforeInitialization以及BeanPostProcessor.postProcessAfterInitialization
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
thrownew BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
//如果是在initializeBean(..)过程中对前面实例化的对象作了改变,那么此时这个提前暴露出去的对象还被别的对象注入过了的话//就会导致不保证单例对象的唯一性了,这里就是负责检查这种情况存在的,如果存在这种情况,可以通过getBeanNamesOfType 的allowEagerInit设置为false//强制不使用earlyExposed的单例对象。if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
elseif (!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()) {
thrownew 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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.// 如果对象指定了destroy方法 或者 需要destroy 将此对象注册到disposable列表中(如果是基于其他scope的 注册到对应scope的 destroy回调中)try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
thrownew BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
总结:
spring通过AbstractBeanFactory.getBean(..)创建bean的整个过程中,如果是singleton 会优先通过
SingletonBeanRegistry.getSingleton(..)来获取单例对象,因此spring中的单例模式并不是使用设计
模式中常用的方法来实现的,而是在集合中维护,并通过同步(synchronization)保证对象只会创建一份来实现的,
如果不不存在,则会执行对象创建的逻辑,而由于spring提供的是一个IOC容器,不止于创建对象,还包括
对象依赖、声明周期(init、destroy)管理以及对象各个阶段的回调拓展(BeanPostProcessor系列接口)
等等
由于在对象执行初始化之前,要将对象实例化、依赖注入完毕,因此就会有循环引用的问题。
比如单例的循环依赖:
A实例的初始化 在依赖于B对象的实例(不是构造器上的依赖关系,而是成员属性中的依赖关系,构造器这种依赖关系是无解的)
class A{
B b;
//setter..
}
class B {
A a;
//setter..
}
这种关系在spring中的创建过程是:
先根据A的无参构造器创建出A 在执行初始化方法前 会先进行getBean(B) 注入到A中,这时 会触发
B对象的创建,而B在初始化方法前,也会注入A 这时getBean(A) 能获取到A实例的earlyExpose的一个引用,因此B注入成功
这时B进行初始化完毕,A 注入成功,A初始化完毕。
prototype类型的对象这样的循环依赖就比较容易了,最终会产生 (A1 -> B -> A2) 3个对象。而单例对象 由于只能存在2个对象
所以才需要特殊处理一下来实现。