Spring Boot 启动过程(四):将 beanDefinition 变成 bean

Spring Boot 启动过程:
1. 创建 SpringApplication 对象。
2. 执行对象的 run() 方法。
3. 将 class 变成 beanDefinition。
4. 将 beanDefinition 变成 bean
5. 图解 循环依赖
6. 图解 bean 的生命周期
7. 图解 aop 拦截器链调用


还剩下最后一个阶段: beanDefinition --> bean。该阶段是在下面的方法中执行的。

/** AbstractApplicationContext.java
*/
public void refresh() throws BeansException, IllegalStateException {
    // ....
    // 实例化所有剩余(非懒加载)的单例。
    finishBeanFactoryInitialization(beanFactory);
}

在执行finishBeanFactoryInitialization(beanFactory); 方法前,所有的配置类都已经变成了 beanDefinition 保存 beanFactory 的 beanDefinitionMap 中。现在执行 finishBeanFactoryInitialization(beanFactory)方法是为了让 所有的 beanDefinition 变成 bean。

大体的流程是:遍历 beanDefinitionMap 中的每一个 beanDefinition,从里面拿出 className,以 className 为依据,去 beanFactory 的 singletonObject 属性中去拿对应名字的 bean。如果能拿到,那就表示该 beanDefinition 已经变成 bean了,否则就用 beanDefinition 创建新 bean 并保存到 singletonObject 中。

1. finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)

/** AbstractApplicationContext.java
	beanFactory 的类型是 DefaultListableBeanFactory
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 注册类型转换器:ConversionService 对象
    // 这里简单看下,套路都是差不多的。
    // 判断 beanFactory 中有名字是 CONVERSION_SERVICE_BEAN_NAME 且类型是 ConversionService.class 的 bean 或者 beanDefinition。
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        // 判断通过了,getBean() 拿 名字是 CONVERSION_SERVICE_BEAN_NAME 且类型是 ConversionService.class 的 bean,
        // 如果能拿到就返回 bean,如果拿不到就创建这样名字和类型的 bean,保存到 singleObject ,再返回 bean。
        // 最后 setConversionService(bean) 向 beanFactory 注册类型转换器。
        beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

	// 如果没有就添加...,有就跳过。
    // 这是给 beanFactory 添加了 value 解析器,主要用于 @Value 注解的解析。
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 实例化 LoadTimeWeaverAware beans。
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 禁止使用临时的类加载器
    beanFactory.setTempClassLoader(null);

    // 禁止再对已注册的 beanDefinition 做修改,因为接下来要开始创建 bean 了。
    beanFactory.freezeConfiguration();

    // 重点在这里。
    // 实例化所有剩余的(非懒加载)的单例。
    beanFactory.preInstantiateSingletons();
}

2. preInstantiateSingletons()

/** AbstractApplicationContext.java
*/
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }
	// 获取所有已注册的 beanDefinition name。
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 遍历,为每一个 name 执行实例化。
    for (String beanName : beanNames) {
        /**
        	如果 beanFactory 的 mergedBeanDefinition 属性有 beanName 对应的 beanDefinition,那就直接返回,
        	否则,从 beanDefinitionMap 中拿出 beanName 对应的 beanDefinition 再合并成(可能) RootBeanDefinition 类型的
        	beanDefinition 保存到 mergedBeanDefinition 属性中,同时也将合并后的 beanDefinition 返回。
        */
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 如果 不是抽象的 且 是单例 且 不是懒加载的,才能实例化。
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 再判断 bd 有没有实现 FactoryBean 接口。
            if (isFactoryBean(beanName)) {
                // 如果实现了,那这里是要实例化 FactoryBean 的,所以 beanName 前面要加 ‘&’ 前缀。
                // 拿出来的 bean 的类型是 FactoryBean。(Factorybean 应该已经被注册了)
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                // 为了保险起见,这里又再判断了下。(如果没有这个判断,下面的强制类型转换会报 warning)
                if (bean instanceof FactoryBean) {
                    // 强制类型转换。
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    // 标志符,表示是否提前实例化 FactoryBean.getObject() 返回的对象。
                    boolean isEagerInit;
                  	// 接下来是,两种场景下修改 isEagerInit 标志符
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        // (1) 系统安全管理开启的模式下。
                        isEagerInit = AccessController.doPrivileged(
                            (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                            getAccessControlContext());
                    }
                    else {
                        // (2) 系统安全模式位开启的模式下。
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                       ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    // 如果可以提前实例化 FactoryBean.getObject() 返回的对象
                    if (isEagerInit) {
                        // 那就实例化,
                        getBean(beanName);
                    }
                }
            }
            else {
                // 如果 bd 没有实现 FactoryBean 接口,那就简单了,当做普通类直接实例化就行了。
                getBean(beanName);
            }
        }
    }
    // 到这里 beanDefinition 就变成了 bean 并注册了。

    // 后置初始化 bean。
    // 遍历 beanNames
    for (String beanName : beanNames) {
        // 获取对应的 bean
        Object singletonInstance = getSingleton(beanName);
        // 如果这个 bean 是 SmartInitializingSingleton 类型的。
        if (singletonInstance instanceof SmartInitializingSingleton) {
            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                .tag("beanName", beanName);
            // 类型转换
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            // 接下来是两种不同的场景下执行 afterSingletonsInstantiated() 方法。
            if (System.getSecurityManager() != null) {
                // 系统安全管理开启的情况下。
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                // 系统安全管理未开启的场景下。
                smartSingleton.afterSingletonsInstantiated();
            }
            // 结束。
            smartInitialize.end();
        }
    }
}

3. isFactoryBean(String name)

/** AbstractBeanFactory.java
	判断给定 name 的 bean 是不是 FactoryBean,返回 false 表示 bean 存在但它不是 FactoryBean
*/
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    // 规范 name
    String beanName = transformedBeanName(name);
    //  从 singletonObject 中拿对应的 bean。
    Object beanInstance = getSingleton(beanName, false);
    // 如果能拿到
    if (beanInstance != null) {
        // 判断 bean 是不是 FactoryBean 类型,并将结果返回。
        return (beanInstance instanceof FactoryBean);
    }
    // No singleton instance found -> check bean definition.
    // 如果拿不到实例,那就再看下 beanName 对应的 beanDefinition 在 当前的 beanFactory 中有没有。
    // 如果当前的 beanFactory 中没有该 beanDefinition,而且当前的 beanFactory 还有父类。 
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        // No bean definition found in this factory -> delegate to parent.
        // 那就递归,父类中找 bean 或者 beanDefinition,知道确认到底是不是 FactoryBean。
        return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
    }
    // 如果 beanFactory 中有 beanName 对应的 beanDefinition,那从 beanDefinition 中判断是不是 FactoryBean。 
    return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

//---------------------
/**
	从 beanDefinition 中判断是否是 FactoryBean。
*/
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    // 先直接从 beanDefinition 中拿结果。
    Boolean result = mbd.isFactoryBean;
    // 如果拿不到
    if (result == null) {
        // 就从 beanDefinition 中推断 bean 的类对象
        Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        // 从类对象中判断是否是 FactoryBean。
        result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
        // 将结果赋值给 beanDefinition。
        mbd.isFactoryBean = result;
    }
    // 返回结果。
    return result;
}

4. getBean(String name)

/** AbstractBeanFactory.java 
	获取指定 name 的 bean。
*/
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
//------------
protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
	// 解析 name,其实是去掉 ‘&’ 符号。
    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
    // 从 beanFactory 中拿 beanName 对应的 bean。(总共有三级缓存)
    Object sharedInstance = getSingleton(beanName);
   	// 判断能不能拿到?
    if (sharedInstance != null && args == null) {
        // 如果拿到了。
        // 日志相关的,先不管。
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                             "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        /**
        	接下来还要判断 sharedInstance 有没有实现 FactoryBean 接口,如果没有实现,那就是普通的bean,直接返回就行。
        	如果实现了 FactoryBean 接口,那还需要再判断下,程序意图是要获取什么东西,是 FactoryBean 对象?还是
        	FactoryBean.getObject() 返回的对象。
		*/
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // (如果从 beanFactory 中拿不到 beanName 对应的 bean,那就需要创建 bean 了)。
		
        // 如果 beanName 对应的 bean 是 Prototype 类型的,且目前处于正在创建中,那就报异常。
        // spring 只能解决 singleton 类型的循环依赖。
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
		
        /**
        	 创建 bean 是需要 beanDefinition 的,如果当前 beanFactory 中没有 beanName 对应的
        	 beanDefinition,那就去 beanFactory 的父类中去找。代码里使用了递归,知道找到为止。
        */
        // 先获取当前 beanFactory 的父类对象 parentBeanFactory。
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 判断父类存在,并且当前 beanFactory 中没有 beanName 对应的 beanDefinition。
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 如果真是这样,那就从父类对象中找 beanDefinition。
            // 获取name,
            String nameToLookup = originalBeanName(name);
            // (没有 instanceof,if 代码块中的类型转化会包 warning)
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                // 类型转化,再调用 doGetBean() 方法。(这里以及下面三个都是递归调用)
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }
        /**
        	无论上面有没有执行递归,能执行到这里两点是可以确定的:
        	1. 在当前的 beanFactory 中没有找到 beanName 对应的 bean;
        	2. 在当前的 beanFactory 中找到了 beanName 对应的 beanDefinition。
        	接下来真要创建 bean 了。
        */

        // 如果获取 bean 不是因为类型检查,而是要正真的使用 bean,
        // 那么需要将 beanName 保存到 beanFactory 的 Set<String> alreadyCreated 字段中。
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        // 阶段记录,先不管它。
        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
            .tag("beanName", name);
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }
            // 把 beanDefinition 拿出来。
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 在检查下。
            checkMergedBeanDefinition(mbd, beanName, args);
            
            /**
            	接下来是要判断,beanName对应的 bean 有没有 @dependOn 其他的 bean?
            	如果有,那得先创建这些依赖的 bean,然后才能创建 beanName 对应的 bean。
            	
            	@Component
				@DependsOn("b")
				public class A {}

				@Component
				public class B {}
            	
            	当下在创建 A 的 bean,那先得创建 b 的 bean ,如果 B 类上有 @DependsOn("a"),
            	立马报异常。经常被使用在观察者模式中。
            */
            // 获取当前 bean @dePendsOn 的其他 bean 的 name。  
            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 + "'");
                    }
                    // 注册 beanName 和它依赖的 bean的对应关系,如果 beanName 对应的 bean 要被销毁,那得先销毁它依赖的 bean。
                    registerDependentBean(dep, beanName);
                    try {
                        //  调用 getBean 方法,dep 对应的 bean 存在就直接拿,不存在就创建。
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }
            
           	/**
           		执行到这里,beanName 对应的 bean 依赖的 bean 都已经被创建了。
           		开始创建 beanName 对应的 bean。
           	*/
            
            // 判断是不是单例的? 
            if (mbd.isSingleton()) {
                // 如果是,那就先 createBean() 创建 bean,再 getSingleton() 将 bean 拿出来。
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                       	// 如果创建出现异常就销毁 bean。
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                /**
        			这里也是一样的,还要判断 sharedInstance 有没有实现 FactoryBean 接口,如果没有实现,那就是普通的bean,直接返回就行。
        			如果实现了 FactoryBean 接口,那还需要再判断下,程序意图是要获取什么东西,是 FactoryBean 对象?还是
        			FactoryBean.getObject() 返回的对象。
				*/
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
			// 判断是不是 Prototype 类型的?
            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);
                }
                beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                // 如果是其他类型。
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                }
                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);
                        }
                    });
                    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        }
        catch (BeansException ex) {
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
        finally {
            beanCreation.end();
        }
    }
	// bean 创建出来了,这里还要判断下 创建出来的 bean 是不是我们需要的类型,
    // 如果是直接返回 bean,如果不是就报异常。
    return adaptBeanInstance(name, beanInstance, requiredType);
}

5. getObjectForBeanInstance(

Object beanInstance, String name, String beanName, RootBeanDefinition mbd)

/** AbstractBeanFactory.java
	从给定的 beanInstance 获取 bean,可能是它自己本身,也可能是它通过执行 FactoryBean 接口的 getObject() 方法创造出来的 bean。
*/
protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    // 判断 name 是以 ‘&’ 开头的?
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        // 如果是,那表示程序意图拿 FactoryBean 的 Bean,此时 beanInstance 应该是实现了 FactoryBean 接口的。
        // 判断 beanInstance 是 空 bean(相当于 null)
        if (beanInstance instanceof NullBean) {
            // 如果是,那就返回空 bean。
            return beanInstance;
        }
       	// 判断 beanInstance 有没有实现 FactoryBean 接口。
        if (!(beanInstance instanceof FactoryBean)) {
            // 如果没有,那就报异常。因为程序意图拿 FactoryBean 的 bean,但 beanInstance 不是 FactoryBean 类型的。
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        // (到这里,表示 beanInstance 实现了 FactoryBean 接口。)
        // 赋值。
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        // 直接返回 FactoryBean 类型的 beanInstance。
        return beanInstance;
    }
    
    /**
    	到这里说明,name 不是以 ‘&’ 开头的,程序意图是拿普通 bean。
    	如果 beanInstance 本身就是普通 bean,那直接返回就可以了。
    	如果 beanInstance 实现了 FactoryBean 接口,那得返回执行 
    	beanInstance.getObject() 方法的结果。
    */
    // 判断 beanInstance 有没有实现 FactoryBean 接口 
    if (!(beanInstance instanceof FactoryBean)) {
        // 如果没有,那说明 beanInstance 是普通 bean,直接返回就可以了。
        return beanInstance;
    }
	
    /**
    	到这里,说明 beanInstance 实现了 FactoryBean 接口,真正要返回给调用
    	者的是 beanInstance.getObject() 方法中创建的创建的 bean。
        
        这种 bean 被创建一次后保存到 beanFactory 的 factoryBeanObjectCache 属性中
        缓存起来。所以,程序执行是先到 factoryBeanObjectCache 去拿 bean,如果拿不到了
        在执行 getObject() 方法创建 bean,缓存一份,返回一份。
	*/
    
    // object 接口最终的结果。
    Object object = null;
    // 赋值 
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        // 如果 mbd 是空,从 factoryBeanObjectCache 中依据 beanName 拿 bean。
        object = getCachedObjectForFactoryBean(beanName);
    }
    // 如果没有拿到,
    if (object == null) {
        // 那就得通过执行 FactoryBean.getObject() 方法来拿到 bean 了。
        // 向上转型。
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // 获取 beanDefinition
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        // 表示位 beanDefinition 是不是合成的(synthetic)
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        // 从 FactoryBean 中获取 bean。
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    // 返回拿到的 bean。
    return object;
}

6. getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)

/** FactoryBeanRegistrySupport.java
	从给定的 FactoryBean 中获取 bean。
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    // 判断 factroy 是单例的,且 已经被实例化了。
    if (factory.isSingleton() && containsSingleton(beanName)) {
        // 如果真是这样的
        synchronized (getSingletonMutex()) {
            // 先从 factoryBeanObjectCache 缓存中拿 beanName 对应的 bean。
            Object object = this.factoryBeanObjectCache.get(beanName);
            // 判断有没有拿到?
            if (object == null) {
                // 如果从缓存中没拿到,那就要调用方法创建了。
                object = doGetObjectFromFactoryBean(factory, beanName);
                // 当 beanName 的 factory 在执行 getObject 方法时,可能会出现循环依赖,结果把要拿的 bean 已经产生并且存到了 
                // factoryBeanObjectCache 里面。
                // 所以这个时候还要到 factoryBeanObjectCache 中再拿一次。
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    // 如果拿到了,就放弃刚创建的,使用已经缓存的。因为已经缓存的不需要再执行什么后置处理了。
                    object = alreadyThere;
                }
                else {
                    // 如果第二次从缓存中没有也没有拿到,那说明 getObject() 方法是第一次执行
                    // 判断要不要执行后置处理:beanPostProcessor。
                    if (shouldPostProcess) {
                        // 如果 beanName 对应的 bean 是单例,且正在创建中。
                        //(这块感觉有点矛盾,方法开头已经判断 beanName 被实例化了,这里又正在创建中。)
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // 临时返回没有执行过后置处理的 object,也不保存。
                            return object;
                        }
                        // 将 beanName 添加到 Set<String> singletonsCurrentlyInCreation 中。
                        beforeSingletonCreation(beanName);
                        try {
                            // 在 object 执行 beanPostProcessor。
                            // 调用每一个 beanPostProcessor 的 postProcessAfterInitialization()方法。
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                                            "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            // 将 beanName 从 Set<String> singletonsCurrentlyInCreation 中移除。
                            afterSingletonCreation(beanName);
                        }
                    }
                    if (containsSingleton(beanName)) {
                        // 缓存 FactoryBean.getObject() 得到的 object。
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            // 如果从 缓存中拿到了 beanName 对应的 bean,直接返回,这个方法执行完了。
            return object;
        }
    }
    else {
        // 如果 factory 不是单例的。
        // 直接从 Factorybean 中拿 object。
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        // 判断是否要执行 bePostProcessor。
        if (shouldPostProcess) {
            try {
                // 在 object 执行 beanPostProcessor。
                // 调用每一个 beanPostProcessor 的 postProcessAfterInitialization()方法。
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        // 返回 object。
        return object;
    }
}

7. doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName)

/** FactoryBeanRegistrySupport.java
	从给定的 Factorybean 中获取 bean。 以 ‘do’ 开头的方法都TM是真正干活的。
*/
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
    // object 保存最后结果。
    Object object;
    try {
        // 两种不同场景下执行 factory.getObject() 方法。
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            // 1. 如果开启了系统安全管理。
            try {
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 2. 如果没开启。
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // factory.getObject() 不允许返回 null,但是可以使用 new NullBean() 代替。
    if (object == null) {
        // 又是循环依赖。
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        object = new NullBean();
    }
    // 返回 object。
    return object;
}

8. createBean(String beanName, RootBeanDefinition mbd, Object[] args)

/** AbstractAutowireCapableBeanFactory.java
	根据给定的、合并后的 beanDefinition:mbd 和参数:args,创建 bean 实例。
	mbd 必须是已经合并后的。
*/
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    // mbdToUse 是要拿来被创建 bean 的。
    RootBeanDefinition mbdToUse = mbd;

    /**
    	从 mbd 中拿出待创建的 bean 的 Class 对象,如果 mbd 已经持有了 Class 对象,那么直接返回。
    	如果没有持有,那就要使用类加载器加载Class,并将 Class对象 set 到 beanDefinition 中。 
    */
    // (beanName 在抛异常时会被用到描述信息中)
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        // 使用原来的 mbd 构建出新的 beanDefinition 对象。
        mbdToUse = new RootBeanDefinition(mbd);
        // set resolvedClass。
        mbdToUse.setBeanClass(resolvedClass);
    }
	// 到这里,beanDefinition 就完成了,接下来应该要创建 bean 了。
    try {
        // 准备方法重写,主要是处理 lookup-method 方法重写。
        // lookup-method 的作用跟 FactoryBean 执行 getObject() 方法时的效果很像,返回一个指定的对象。
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 执行 beanPostProcessor 可以让其返回一个 proxy 对象代替创建目标 bean。
        // 实际上是在执行实现 InstantiationAwareBeanPostProcessor 接口的 BeanPostProcessor。
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            // InstantiationAwareBeanPostProcessor 生成了bean,那么这个bean将取代起初要创建的目标 bean 作为结果返回。
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }
    // 执行到这里,表示 InstantiationAwareBeanPostProcessor 没有生成 proxy。
    // 那就要真正创建 target bean。
    try {
        // 创建 target bean。
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        // 返回结果。
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

9. doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args)

/** AbstractAutowireCapableBeanFactory.java
	以 'do' 开头的方法都是真正干活的。
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // bean 的包装类对象。
    BeanWrapper instanceWrapper = null;
    // 如果 mbd 是单例的
    if (mbd.isSingleton()) {
        // 那要清楚缓存中的 bean。
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // 如果 instanceWrapper 为空
    if (instanceWrapper == null) {
        // 创建
        // createBeanInstance() 主要的内容是判断优先从哪儿拿什么样的构造器,
        // 选定构造器后创建了 beanInstance,然后将 beanInstance 封装在了 BeanWrapper 对象中,
        // 最后再给 beanWrapper 对象 set 了一些属性,比如 ConversionService,就返回了。
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 从包装类中拿出 bean。
    Object bean = instanceWrapper.getWrappedInstance();
    // 从包装类中拿出 bean 的类型。
    Class<?> beanType = instanceWrapper.getWrappedClass();
     // 如果 beanType 不是空类型。
    if (beanType != NullBean.class) {
        // 赋值。
        mbd.resolvedTargetType = beanType;
    }
	/**
		调用 beanPostProcessor 对 beanDefinition 进行修改。
		这里可能会疑惑,bean 都已经被创建出来了,还修改 beanDefinition 有什么用呢?
		上面只是 “创建” 了 bean,此时的 bean 还是不完整的,接下来还需要给 bean 填充属性值,
		执行初始化。
		
		填充的一部分属性值就是从 beanDefinition 中拿出来的。所以 beanPostProcessor 修改了
		beanDefinition,就相当于是“后置”修改了刚刚创建出来的 bean。
	*/
    
    synchronized (mbd.postProcessingLock) {
        // postProcessed 标志位,表示 MergedBeanDefinitionPostProcessor 有没有执行过,默认是 false。
        if (!mbd.postProcessed) {
            try {
                // 在这里调用了 beanPostProcessor 对 bean 做修改,其中:
                // CommonAnnotationBeanPostProcessor 扫描了 @PostConstruct @PreDestroy @Resource 注解;
                // AutowiredAnnotationBeanPostProcessor 扫描了  @Autowired @Value 注解;
                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.
    // 是否需要提前暴露 = 是单例 且 自动解决循环依赖 且 当前 bean 正在创建中
    // (肯定是提前暴露的,因为就是是单例,默认自动解决循环依赖,bean 肯定在创建中)
    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");
        }
        // (这块是解决循环依赖的,将 “不完全的 bean“ 放入第三级缓存中)
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // 前面只是创建了 bean 实例,现在要初始化 bean实例,就是 set 属性值。
    Object exposedObject = bean;
    try {
        // 用 mbd 中的属性值填充 instanceWrapper 中的 bean 的属性(循环依赖会在这里解决)。
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化,依旧是 set了一些属性值:
        // 设置 Aware 相关的属性,如 beanName、classloader、beanFactory。
        // 调用 beanPostProcessor 执行 postProcessBeforeInitialization() 方法。 
        // 如果 bean 实现了 InitializingBean 接口,那执行 afterPropertiesSet() 方法。
        // 调用 beanPostProcessor 执行 applyBeanPostProcessorsAfterInitialization() 方法。
        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);
        }
    }

    // 这个判断在 Spring Boot web 程序启动时肯定是成立的。
    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.");
                }
            }
        }
    }

    // 设置 bean 的销毁。
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

10. registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd)

/** AbstractBeanFactory.java
	这里是在设置 bean 的销毁方式,单例 bean 的销毁方式有三种:
	1. DestructionAwareBeanPostProcessors;
	2. 实现 DisposableBean 接口,执行 destroy() 方法;
	3. 自定义 destroy 方法。
	
	注:上面三中方式不是删除 bean,二是在当 bean 被删除时要执行一些逻辑,至于是这么逻辑,可以写在那些方法中。
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    // 获取权限。
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    // 判断 bean 不是 Prototype 类型的 ,且需要销毁。
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        // bean 是单例
        if (mbd.isSingleton()) {
            // 将 bean 封装在 DisposableBean 的实现类 DisposableBeanAdapter 中,保存到 beanFactory 的 (Map)disposableBeans 属性中。
            registerDisposableBean(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
        else {
            // bean 不是单例。
            // bean 有自定义的 scope。
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            // 也是将 bean 封装在 DisposableBean 的实现类 DisposableBeanAdapter 中,注册到 scopes 的 (Map)destructionCallbacks 属性中。
            scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
    }
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值