zoukankan      html  css  js  c++  java
  • Spring(八)核心容器

    Spring 版本 5.0.7.RELEASE

    获取 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);
    }
    

    以上主要分为:

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

    不管是通过工厂方法还是构造方法来实例化对象,到这里得到的也仅仅是一个 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 的生命周期。关于钩子接口在上一篇的《Spring(七)核心容器 - 钩子接口》文章已详细讨论,感兴趣的同学可自行翻阅。

    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源码深度解析(第2版)》

  • 相关阅读:
    HTTPS和HTTP的区别
    .NET反射、委托技术与设计模式
    中文化和国际化问题权威解析之三:Java中文问题分析
    Windows下Critical Section、Event、Mutex、Semaphores区别
    使用Forms Authentication 身份验证 之 Basic Knowledge
    介绍几个java虚拟机性能监测工具
    理解Semaphore和Mutex
    中文化和国际化问题权威解析之四:Java中文化和国际化攻略
    中文化和国际化问题权威解析之一:字符编码发展历程
    Happy new year!
  • 原文地址:https://www.cnblogs.com/loongk/p/12563304.html
Copyright © 2011-2022 走看看