Spring核心容器之Bean创建过程详解

 更新时间:2023年11月17日 08:41:13   作者:龙三丶  
这篇文章主要介绍了Spring核心容器之Bean创建过程详解,获取 Bean 的方法是 getBean,其来自 BeanFactory 继承的AbstractAutowireCapableBeanFactory 抽象类继承的AbstractBeanFactory 抽象类中,需要的朋友可以参考下

前言

获取 Bean 的方法是 getBean,其来自 BeanFactory 继承的 AbstractAutowireCapableBeanFactory 抽象类继承的 AbstractBeanFactory 抽象类中。

1、整体流程

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    
    ...
    // 通过 beanName 获取 Bean 实例
    @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

    // 检索所需的 bean 类型
	@Override
	public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
		return doGetBean(name, requiredType, null, false);
	}

    // 使用显式参数创建 Bean 实例时要使用的参数
	@Override
	public Object getBean(String name, Object... args) throws BeansException {
		return doGetBean(name, null, args, false);
	}
	
    ...
}

getBean 有多个重载方法,可分为通过 Bean 名称或通过 Class 获取 Bean 对象,这些重载方法底层都是调用 doGetBean 方法。

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    /**
	 * 1、如果获取的 Bean 类型是 FactoryBean,则参数 name 会以“&”为前缀。这里会去掉该修饰符,并返回.
	 * 2、如果是手动注册的别名,则将其解析为规范的名称
	 */
	final String beanName = transformedBeanName(name);
	Object bean;

    /** 
     * 1、单例 Bean 在 Spring 的同一个容器内只会被创建一次,后续再获取 Bean,直接从单例缓存中获取
     * 2、这里先从单例 Bean 的缓存容器中,尝试获取目标 Bean 
     * ( getSingleton 方法中存在解决单例 Bean 循环依赖问题的具体方案,这部分会在后面的章节详细讨论)
     */ 
	Object sharedInstance = getSingleton(beanName);
	
	// 如果存在目标 Bean
    if (sharedInstance != null && args == null) {
        if (logger.isDebugEnabled()) {
        
            // 目标 Bean 是否正在被创建
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }

        // 1、不论是单例还是原型的实例对象,最终都要通过 getObjectForBeanInstance 进行转换,最终得到的才是符合要求的bean实例。
        // 2、有时候存在如 FactoryBean 这种并不是直接返回实例本身,而是返回指定方法返回的实例
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    // 如果不存在目标 Bean
    else {
    
        // 如果当前正在创建原型 Bean,则处于循环依赖中,且原型 Bean 无法解决循环依赖,所以抛出异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 如果 beanDefinitionMap 也就是容器中不存在目标 Bean,则尝试从父级 beanFactory 中获取
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 获取真正 beanName。如果获取的 Bean 类型是 FactoryBean,则去掉 beanName 的修饰符“&”
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // 递归到 BeanFactory 中寻找
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        if (!typeCheckOnly) {
            // 将指定的 bean 标记为已经创建(或将要创建),即将 beanName 加入 alreadyCreated 集合中
            markBeanAsCreated(beanName);
        }

        try {
            // 通过 beanName 获取对应的 BeanDefinition,如果获取 BeanDefinition 是子类 BeanDefinition,
            // 则通过与父级合并,返回目标 bean 的 RootBeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 检查bean是否是抽象的,如果是则抛出异常
            checkMergedBeanDefinition(mbd, beanName, args);

            // 获取目标 bean 所依赖的其它 bean 名称
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                // 若存在依赖则需要递归实例化依赖的 bean
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            /* 开始创建目标 bean 实例,根据 bean 的 scope  执行不同的创建方式。单例,原型,其他的scope */

            // 这是单例的 bean 创建方式
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 创建 Bean 的核心方法
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // prototype 类型的 bean 创建方式
            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            // 其它类型
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 将 Bean 的类型转换为 getBean 时指定的 requireType 类型
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

整个方法的过程可以概括为:

  1. 解析 beanName
  2. 从单例 Bean 实例的缓存容器中,尝试获取目标 Bean ,若存在,则直接执行最后一步,将 Bean 的类型转换为 getBean 时指定的 requireType 类型,之后返回
  3. 若不存在,则进入创建 Bean 实例的流程
  4. 如果当前正在创建原型 Bean 实例,则处于循环依赖中,且原型 Bean 无法解决循环依赖,所以抛出异常
  5. 如果当前 BeanFactory 中不存在目标 BeanDefinition,则从父 BeanFactory 获取
  6. 获取目标 BeanDefinition,如果获取的 BeanDefinition 是子类 BeanDefinition(如 GenericBeanDefinition),则通过与父级合并,返回目标 bean 的 RootBeanDefinition
  7. 如果存在依赖的 Bean,则先实例化这些依赖的 Bean
  8. 依据当前 Bean 的作用域,开始实例化 Bean ,单例或原型
  9. 判断实例化的 Bean 是否是 FactoryBean 类型
  10. 将 Bean 的类型转换为 getBean 时指定的 requireType 类型
  11. 最后返回 Bean 实例

以上就是 getBean 方法的大致流程,其中有两个频繁出现且非常重要的方法,一个是处理 FactoryBean 的 getObjectForBeanInstance方法,另一个是创建 Bean 的核心实现 createBean 方法。

2、核心流程

2.1 解析 FactoryBean

关于 FactoryBean 在上一篇《Spring(七)核心容器 - 钩子接口》文章中已经讨论过,FactoryBean 是 Spring 提供的钩子接口,其属于一种特殊的 Bean,不同于普通的 Bean,它是用来创建 Bean 实例的,属于工厂 Bean,不过它和普通的创建不同,它提供了更为灵活的方式,一般用来创建那些创建过程比较复杂的 Bean。

而 FactoryBean 则是通过 getObjectForBeanlnstance 进行解析。getObjectForBeanlnstance 是个高频率使用的方法,无论是从缓存中获得 bean 还是根据不同的 scope 策略加载bean。总之,我们得到 bean 的实例后要做的第一步就是调用这个方法来检测一下正确性,其实就是用于检测当前 bean 是否是 FactoryBean 类型的 bean ,如果是,那么需要调用该 bean 对应的 FactoryBean 实例中的 getObject() 方法返回值作为真正返回的对象。

所以,当我们 getBean 的时候,有两种可能,一种是返回普通的 Bean,另一种是返回通过 getObjectForBeanInstance 方法解析 FactoryBean 返回的 Bean。

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// 如果 beanName 以“&”为前缀,但对应的 bean 不是 FactoryBean 类型,则抛异常
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}
	}

	// 校验已获取的 bean 
	// 1、如果该 bean 不是 FactoryBean 类型,直接返回
	// 2、如果是 FactoryBean 类型,且 beanName 以“&”为前缀,说明想获取的是 FactoryBean ,也是直接返回
	if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
		return beanInstance;
	}

    // 从缓存中尝试获取 FactoryBean 创建的对象
	Object object = null;
	if (mbd == null) {
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// 到这里已确定 beanInstance 一定是 FactoryBean 类型,所以进行强转
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// 获取 bean 对应的 BeanDefinition
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		// 当前 bean 是否是用户定义的,而不是应用程序自己定义的
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		
		// 解析 FactoryBean 的核心方法
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}

这个方法很简单,大多是些辅助代码以及一些功能性的判断,真正的核心代码在 getObjectFromFactoryBean 方法中。

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    // 如果是单例 bean 
	if (factory.isSingleton() && containsSingleton(beanName)) {
		synchronized (getSingletonMutex()) {
		    // 尝试从缓存中获取,缓存中存储的是已经通过 FactoryBean 创建的 bean 
			Object object = this.factoryBeanObjectCache.get(beanName);
			if (object == null) {
			
			    // 通过 FactoryBean 创建真正的 bean 
				object = doGetObjectFromFactoryBean(factory, beanName);
				
				// 这里大概是 在执行上一步 doGetObjectFromFactoryBean 方法过程中,该 bean 已被其它线程创建并缓存了起来
				Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
				if (alreadyThere != null) {
					object = alreadyThere;
				}
				else { // 如果没有
					if (shouldPostProcess) { // Bean 是否要进行后置处理
						...
						
						try {
						    // 执行后置处理器(关于后置处理器已在上篇文章讨论过)
							object = postProcessObjectFromFactoryBean(object, beanName);
						}
						
						// catch ...
					}
					...
				}
			}
			return object;
		}
	}
	else { // 如果不是单例 bean 
	    // 通过 FactoryBean 创建真正的 bean 
		Object object = doGetObjectFromFactoryBean(factory, beanName);
		if (shouldPostProcess) {
			try {
			    // 执行后置处理器
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			// catch ...
		}
		return object;
	}
}

接着进入该方法中更为核心的 doGetObjectFromFactoryBean 方法:

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {
	Object object;
	try {
		// try...catch...
		else {
		    // 调用 FactoryBean 的 getObject 方法,返回真正的 bean
			object = factory.getObject();
		}
	}
	// try...catch...
	...
	return object;
}

可以看到,最后调用的就是 FactoryBean.getObject 方法

public interface FactoryBean<T> {
	@Nullable
	T getObject() throws Exception;
}

当某个 bean 的实例化过程比较复杂时,可通过实现 FactoryBean 接口,然后在重写的 getObject 方法中定义实例化 bean 的逻辑,以后获取该 bean 时,会通过调用 getObject 方法进行返回。值得注意的是 mybatis 底层就是通过 FactoryBean 来实现。

2.2 从 createBean 开始

接着进入创建 Bean 的下一步 createBean 方法:

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;

	// 根据设置的 class 属性或 className 来解析得到 Class 引用
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// 对 override 属性进行标记和验证,本质上是处理 lookup-method 和 replaced-method 标签
	try {
		mbdToUse.prepareMethodOverrides();
	}
	// catch...

	try {
		// 执行 BeanPostProcessors 后置处理器,如果有 bean 返回,则不执行接下来创建 bean 的操作,直接返回该 bean 
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	// catch...

	try {
	    // 创建 Bean 的核心方法
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	// catch...
}

继续进入 doCreateBean 方法中:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

	// BeanWrapper 包装了 bean 对象,缓存了 bean 的内省结果,并可以访问 bean 的属性、设置 bean 的属性值
	BeanWrapper instanceWrapper = null;
	// 如果是单例,尝试获取对应的 BeanWrapper
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
	    /*
         * 说明对应的bean还没有创建,用对应的策略(工厂方法、构造函数)创建 bean 实例,以及简单初始化
         *
         * 将 beanDefinition 转成 BeanWrapper,大致流程如下:
         * 1. 如果存在工厂方法,则使用工厂方法初始化
         * 2. 否则,如果存在多个构造函数,则根据参数确定构造函数,并利用构造函数初始化
         * 3. 否则,使用默认构造函数初始化
         */
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	// 从 BeanWrapper 中获取包装的 bean 实例
	final Object bean = instanceWrapper.getWrappedInstance();
	// 从 BeanWrapper 获取包装 bean 的 class 引用
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// 执行 MergedBeanDefinitionPostProcessor 后置处理器。
	//(这里涉及一个极其重要的后置处理器实现 AutowiredAnnotationBeanPostProcessor,其主要用来处理 @Autowired 注解,这部分会在后面详细讨论)
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			// catch...
			mbd.postProcessed = true;
		}
	}

	//  检查是否需要提前曝光,避免循环依赖(循环依赖问题会在后面详细讨论)
	boolean 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));
	}

	// 开始初始化 bean 
	Object exposedObject = bean;
	try {
	    // 对 bean 进行填充,将各个属性值注入,如果存在依赖的 bean 则进行递归初始化
		populateBean(beanName, mbd, instanceWrapper);
		// 执行一系列的初始化方法
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	// catch...

    // 再次检查是否循环依赖
	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 
				}
			}
		}
	}

	// 注册DisposableBean
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	// catch...

	return exposedObject;
}

该方法整体流程如下:

  1. 如果是单例,尝试从缓存中获取 bean 的包装器 BeanWrapper,并清除缓存
  2. 如果不存在对应的 Wrapper,则说明 bean 未被实例化,创建 bean 实例
  3. 执行 MergedBeanDefinitionPostProcessor 后置处理器
  4. 检查是否需要提前曝光,避免循环依赖
  5. 属性填充,将所有属性填充至bean 的实例中。
  6. 执行一系列的初始化方法(回调钩子接口)
  7. 再次检查是否存在循环依赖
  8. 注册 DisposableBean

该过程中有几个需要重点介绍的方法,分别是创建 Bean 实例的 createBeaninstance 方法、注入 Bean 属性的 populateBean 方法以及执行 Bean 初始化方法的 initializeBean 方法。

2.2.1 创建 Bean 实例

从 createBeaninstance 开始:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	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());
	}

    // 如果有用于创建 bean 实例的回调方法
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}
    
    // 如果工厂方法不为空,则使用工厂方法进行实例化
	if (mbd.getFactoryMethodName() != null)  {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// 利用构造函数进行实例化,解析并确定目标构造函数
	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);
		}
	}

	// 根据参数确定构造函数
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// 使用默认的构造函数
	return instantiateBean(beanName, mbd);
}

以上主要分为:

  • 使用工厂方法进行实例化
  • 通过构造函数实例化

不管是通过工厂方法还是构造方法来实例化对象,到这里得到的也仅仅是一个 bean 的最初实例,还不是我们最终期望的 bean,因为后面还需要对 bean 实例进行初始化处理,注入相应的属性值等。

2.2.2 初始化 Bean 实例 - 属性注入

属性注入通过 populateBean 方法实现:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // 判断实例化的 bean 是否为空
	if (bw == null) {
	    // 返回是否有为此 bean 定义的属性值,如果有,则抛异常,提示 “无法将属性值应用于空实例”
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		// 没有,则跳过属性填充阶段以获取空实例
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// 在设置属性之前,先执行 InstantiationAwareBeanPostProcessors 后置处理器,这些后置处理器可以用其它方式注入属性,如字段注入。
	boolean continueWithPropertyPopulation = true;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
    // 当使用了 InstantiationAwareBeanPostProcessors 后置处理器注入属性,则结束属性注入流程,直接返回
	if (!continueWithPropertyPopulation) {
		return;
	}

    // 获取 bean 实例的属性值集合
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		// 根据名称自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}

		// 根据类型自动注入
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}

		pvs = newPvs;
	}

    // 返回此工厂是否拥有 InstantiationAwareBeanPostProcessor
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	// 是否进行依赖检查
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

	if (hasInstAwareBpps || needsDepCheck) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		// 在属性注入前执行 InstantiationAwareBeanPostProcessor 后置处理器
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		// 进行依赖检查
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}

	if (pvs != null) {
	    // 执行属性注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

2.2.3 初始化 Bean 实例 - 执行初始化方法(回调钩子接口)

接着进入 initializeBean 方法,在该方法中会回调许多在 Bean 初始化阶段执行的方法。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

    // 回调 Aware 系列接口
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

    // 回调 BeanPostProcessor 后置处理器的 postProcessBeforeInitialization 方法
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
	    // 回调 InitializingBean 的 afterPropertiesSet 方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
	    // 回调 BeanPostProcessor 后置处理器的 postProcessAfterInitialization 方法
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

可以看到,在 Bean 的初始化阶段,分别回调了 Aware 系列接口、BeanPostProcessor 后置处理器、InitializingBean 。这三个接口都属于 Spring 的钩子接口,是 Spring 开放出来的扩展接口,可以影响 Bean 的生命周期。

Bean 的初始化阶段

1、回调 Aware 系列接口

private void invokeAwareMethods(final String beanName, final Object bean) {   
    
	if (bean instanceof Aware) {
	    // 如果当前 Bean 继承了 BeanNameAware 接口,则回调接口中的 setBeanName 方法,并传递 beanName 参数
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		
		// 这个 BeanClassLoaderAware 接口传递的是 ClassLoader
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		
		// 这个 BeanFactoryAware 接口传递的是 AbstractAutowireCapableBeanFactory
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

这里被回调的 Aware 接口有三个,分别是 BeanNameAware 、BeanClassLoaderAware、BeanFactoryAware。

2、回调 BeanPostProcessor 后置处理器的 postProcessBeforeInitialization 方法

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

	Object result = existingBean;
	
	// getBeanPostProcessors 方法获取所有的 BeanPostProcessor 后置处理器的实现,并循环执行 postProcessBeforeInitialization 方法,参数是当前 Bean 以及 beanName 。
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

其中有一个后置处理器的实现 ApplicationContextAwareProcessor ,其用来对剩余的 Aware 接口进行回调:

@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

	//...
	
		invokeAwareInterfaces(bean);
	//...

	return bean;
}
private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}
}

3、回调 InitializingBean 的 afterPropertiesSet 方法

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
	//..
			((InitializingBean) bean).afterPropertiesSet();
	//..
}

4、回调 BeanPostProcessor 后置处理器的 postProcessAfterInitialization 方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {
	Object result = existingBean;
	// getBeanPostProcessors 方法获取所有的 BeanPostProcessor 后置处理器的实现,并循环执行 postProcessAfterInitialization 方法,参数是当前 Bean 以及 beanName 。
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

到这里,创建 Bean 的核心流程就讨论结束,可归纳为:

  1. 解析 beanName
  2. 从单例 Bean 实例的缓存容器中,尝试获取目标 Bean
  3. 缓存不存在则开始实例化 Bean ,区分单例或原型
  4. 实例化 Bean、初始化 Bean、执行初始化方法及回调钩子接口
  5. 判断实例化的 Bean 是否是 FactoryBean 类型

到此这篇关于Spring核心容器之Bean创建过程详解的文章就介绍到这了,更多相关Spring的Bean创建过程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java类的继承原理与用法分析

    Java类的继承原理与用法分析

    这篇文章主要介绍了Java类的继承原理与用法,结合实例形式分析了java类的继承相关原理、使用方法及操作注意事项,需要的朋友可以参考下
    2020-02-02
  • 使用java基础类实现zip压缩和zip解压工具类分享

    使用java基础类实现zip压缩和zip解压工具类分享

    使用java基础类写的一个简单的zip压缩解压工具类,实现了指定目录压缩到和该目录同名的zip文件和将zip文件解压到指定的目录的功能
    2014-03-03
  • java判断integer是否为空的详细过程

    java判断integer是否为空的详细过程

    在java编写过程中,我们会使用到各种各样的表达式,在使用表达式的过程中,有哪些安全问题需要我们注意的呢?对java判断integer是否为空相关知识感兴趣的朋友一起来看看吧
    2023-02-02
  • JPA findById方法和getOne方法的区别说明

    JPA findById方法和getOne方法的区别说明

    这篇文章主要介绍了JPA findById方法和getOne方法的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2021-08-08
  • 详解Java8与Runtime.getRuntime().availableProcessors()

    详解Java8与Runtime.getRuntime().availableProcessors()

    这篇文章主要介绍了详解Java8与Runtime.getRuntime().availableProcessors(),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java如何实现内存缓存

    Java如何实现内存缓存

    内存缓存(Memory caching)是一种常见的缓存技术,它利用计算机的内存存储临时数据,以提高数据的读取和访问速度,本文就来和大家聊聊Java如何实现内存缓存吧
    2023-08-08
  • Java字符串查找的方法总结

    Java字符串查找的方法总结

    在给定的字符串中查找字符或字符串是比较常见的操作,字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符,本文给大家总结了Java字符串查找的方法,需要的朋友可以参考下
    2024-05-05
  • Springboot搭建JVM监控(Springboot + Prometheus + Grafana)

    Springboot搭建JVM监控(Springboot + Prometheus +&n

    在应用开发时,监控报警必不可少,本文主要介绍了Springboot搭建JVM监控(Springboot + Prometheus + Grafana),具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • Java 反转带头结点的单链表并显示输出的实现过程

    Java 反转带头结点的单链表并显示输出的实现过程

    这篇文章主要介绍了Java 反转带头结点的单链表并显示输出,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • springboot2.x整合tkmapper的示例代码

    springboot2.x整合tkmapper的示例代码

    这篇文章主要介绍了springboot2.x整合tkmapper,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01

最新评论