栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

Spring源码分析系列

Spring源码分析-启动流程浅析
Spring源码分析-Spring源码分析-BeanDefinition
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期查找与注册(1)
Spring源码分析-Bean生命周期查找与注册(2)


文章目录

Spring源码分析系列前言一、Bean的注册流程1.1、preInstantiateSingletons二、doGetBean

2.1、从缓存中获取bean对象2.2、从父factorybean中获取对象2.3、根据beanName获取BeanDefinition2.4、创建依赖bean对象2.5、创建bean对象 三、总结


前言

bean的生命周期是重要的知识点,为了能记住这几篇博客都会反复提醒,具体如下:
实例化 --> 属性赋值 --> Bean后置处理器before方法 --> 属性处理器afterProtpertiesSet --> 初始化方法init-method --> Bean后置处理器after方法 --> 对象应用 --> 销毁方法destroy-method --> gc回收。

本篇博客主要分析一下,bean获取与注册流程


一、Bean的注册流程

bean注册流程如下,虽然比较简单,但是最复杂的方法就是doGetBean。

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 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) ((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) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
            smartInitialize.end();
        }
    }
}
 
二、doGetBean 

getBean只是最外层方法,最终会调用doGetBean方法,查找流程图如下:

doGetBean方法,既可以获取bean,又可以实现bean注册,这个方法比较长,分段进行介绍。

2.1、从缓存中获取bean对象
@SuppressWarnings("unchecked")
protected  T doGetBean(
        String name, @Nullable Class 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的获取与注册流程,这个流程是一个大体流程后面还需要深入分析,通过另外一篇进行介绍

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号