Spring源码分析-Bean生命周期查找与注册(1)

Spring源码分析系列

Spring源码分析-启动流程浅析
Spring源码分析-BeanDefinition
Spring源码分析-Bean管理查找与注册(1)
Spring源码分析-Bean管理查找与注册(2)
Spring源码分析-Bean管理循环依赖和三级缓存
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期createBean


文章目录

  • Spring源码分析系列
  • 前言
  • 一、Bean的注册流程
  • 1.1、preInstantiateSingletons
  • 二、doGetBean
    • 2.1、从缓存中获取bean对象
    • 2.2、从父factorybean中获取对象
    • 2.3、根据beanName获取BeanDefinition
    • 2.4、创建依赖bean对象
    • 2.5、创建bean对象
  • 三、总结


前言

从本篇博客开始分析,spring对Bean的管理,本篇博客的主要内容bean获取与注册流程


一、Bean的注册流程

bean注册流程如下,虽然比较简单,但是最复杂的方法就是doGetBean。
Spring源码分析-Bean生命周期查找与注册(1)_第1张图片

1.1、preInstantiateSingletons

该方法是入口,代码核心内容就是循环遍历,然后调用getBean进行bean注册

public void preInstantiateSingletons() throws BeansException {
    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 循环遍历BeanDefinition并且进行注册
    for (String beanName : beanNames) {//循环遍历
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {//是否为工厂bean
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //FactoryBean都是以&开始,注册工厂bean
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(
                                (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName); //注册目标bean
                    }
                }
            }
            else {//其他bean
                getBean(beanName);//注册普通bean
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    // 再次循环遍历,查找bean类型为SmartInitializingSingleton
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                    .tag("beanName", beanName);
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
            smartInitialize.end();
        }
    }
}

二、doGetBean

getBean只是最外层方法,最终会调用doGetBean方法,查找流程图如下:
Spring源码分析-Bean生命周期查找与注册(1)_第2张图片
doGetBean方法,既可以获取bean,又可以实现bean注册,这个方法比较长,分段进行介绍。

2.1、从缓存中获取bean对象

/**
    * Return an instance, which may be shared or independent, of the specified bean.
    * @param name the name of the bean to retrieve
    * @param requiredType the required type of the bean to retrieve
    * @param args arguments to use when creating a bean instance using explicit arguments
    * (only applied when creating a new instance as opposed to retrieving an existing one)
    * @param typeCheckOnly whether the instance is obtained for a type check,
    * not for actual use
    * @return an instance of the bean
    * @throws BeansException if the bean could not be created
    */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {

    String beanName = transformedBeanName(name);//beanName转化
    Object beanInstance; //返回的bean实例对象

    // Eagerly check singleton cache for manually registered singletons.
    // 从缓存中获取实例,这里会从一,二,三级缓存中分别进行查找实例
    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 + "'");
            }
        }
        //对实例对象再次处理,比如说实例对象实现FactoryBean接口(也就是sharedInstance代表是工厂bean),需要调用getObject返回真实对象
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {

    }

2.2、从父factorybean中获取对象

// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {//原型bean,出现了循环引用
    throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    // 在当前对象中没有BeanDefinition,则从父BeanFactory中查找Bean镀锡
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                nameToLookup, requiredType, args, typeCheckOnly);//从父BeanFactory中获取bean对象
    }
    else if (args != null) {
        // Delegation to parent with explicit args.
        return (T) parentBeanFactory.getBean(nameToLookup, args); // 从父BeanFactory中获取bean对象
    }
    else if (requiredType != null) {
        // No args -> delegate to standard getBean method.
        return parentBeanFactory.getBean(nameToLookup, requiredType); //从父BeanFactory中获取bean对象
    }
    else {
        //从父BeanFactory中获取bean对象
        return (T) parentBeanFactory.getBean(nameToLookup);
    }
}

2.3、根据beanName获取BeanDefinition

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);//获取合并后,BeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);

2.4、创建依赖bean对象

// Guarantee initialization of beans that the current bean depends on.
// 依赖的bean先进行初始化
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
	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); //将dep beanName作为关联关系
		try {
			getBean(dep); //注册bean
		}
		catch (NoSuchBeanDefinitionException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
		}
	}
}

2.5、创建bean对象

下面根据类型(单例,原型,其他)创建bean实例,

// Create bean instance.
if (mbd.isSingleton()) {//单例bean
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args); //创建bean对象,底层通过反射方式
        }
        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;
        }
    });
    //对实例对象再次处理,比如说实例对象实现FactoryBean接口(也就是sharedInstance代表是工厂bean)
    // 需要调用getObject返回真实对象
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {//多列bean
    // It's a prototype -> create a new instance.
    Object prototypeInstance = null;
    try {
        beforePrototypeCreation(beanName);
        prototypeInstance = createBean(beanName, mbd, args);//创建bean对象,底层通过反射方式
    }
    finally {
        afterPrototypeCreation(beanName);
    }
    beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {// request or session on WebApp
    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);
    }
}

三、总结

本篇博客,介绍了一下bean的获取与注册流程,这个流程是一个大体流程后面还需要深入分析,通过另外一篇进行介绍

你可能感兴趣的:(Spring家族,spring,getBean)