美文网首页
spring bean的生命周期

spring bean的生命周期

作者: hello_kd | 来源:发表于2020-09-05 13:53 被阅读0次

spring中bean的创建流程,不管是基于注解的方式,还是基于xml,都是需要先将代码中对bean的配置信息先加载到工厂,每个spring容器管理的bean都会有一个BeanDefinition对象,对象的各个属性值就是该bean的元数据信息。然后再根据BeanDefinition对象生成对应的bean实例,而在bean实例的创建过程,有一个非常重要的处理器便是BeanPostProcessor,代码中spring容器默认会添加许多的BeanPostProcessor,也可以在程序自定义BeanPostProcessor,处理器可以在对象的初始化前后做一些特殊处理。

这里还需要注意的是区分实例化和初始化,实例化是生成一个对象了,初始化是bean中定义的init方法,因为在bean的创建过程中,BeanPostProcessor在初始化前后调用,而有的BeanPostProcessor还会在实例化前后做一些事情(BeanPostProcessor子类扩展的方法)

本文主要讲述下这个创建流程,忽略加载BeanDefinition对象到工厂的步骤,直接看创建bean实例,并且不考虑一些循环依赖、factoryBean等等,只是先来了解下最简单的bean实例是如何创建出来的

因此直接从spring容器refresh方法的finishBeanFactoryInitialization入口看源码

public void preInstantiateSingletons() throws BeansException {

    //spring工厂所有的beanName列表
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
//根据beanName获取到对应的BeanDefinition对象
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//如果对象时单例的,且非抽象和延迟初始化的,那么进行初始化操作
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                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);
                    }
                }
            }
            else {
                getBean(beanName);
            }
        }
    }
    
//这里为了更简洁方便理解,将一些代码删掉了,若bean有实现了SmartInitializingSingleton,那么执行这个接口的afterSingletonsInstantiated方法
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
                smartSingleton.afterSingletonsInstantiated();
        }
    }
}

上面这个方法中,主要看下getBean方法,为了方便理解,先将doGetBean的大量代码删了,看下最简单的bean实例是如何创建的

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

    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        //省略
              beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        //省略
        try {
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        //省略
                    }
                });
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

        } catch (BeansException ex) {
            //省略
        } finally {
        //省略
        }
    }
    return adaptBeanInstance(name, beanInstance, requiredType);
}

这个方法主要有三个步骤 getSingleton -----> getObjectForBeanInstance ------> adaptBeanInstance,其中第一步getSingleton 会先看缓存有没有,有的话就直接走第二步了,没有的话,先进行创建,因此来看下创建的方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//防止多个线程来操作缓存,造成并发问题
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            boolean newSingleton = false;
            try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } finally {
            }
            if (newSingleton) {
//添加到spring的缓存中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

getSingleton的逻辑也比较简单,创建的逻辑是根据方法参数传入的SingletonFactory来执行的,通过SingletonFactory创建出实例后,再加入到spring缓存中,因此流程又转到SingletonFactory的工厂方法getObject中,而getObject方法内部又是执行createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    RootBeanDefinition mbdToUse = mbd;
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        return beanInstance;
    }
}

从这个方法看到了前面提到的BeanPostProcessor,BeanPostProcessor在这里有机会返回一个代理对象,而不是执行spring的doGetBean方法。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
//BeanPostProcessor实例化前被执行的方法,若返回对象了,那么也会接着执行初始化后的方法,这里注意区分两个方法,一个是实例化前,一个是初始化后
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

若BeanPostProcessor没有返回代理对象,那么执行doCreateBean方法,这个方法是整个bean创建的核心方法,我们这里先不考虑循环依赖等等,

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
//获取bean对象的实例,这里需注意的是,此时bean的属性还未被设置,可以理解现在只是new出来一个对象
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // 允许BeanPostProcessor对bean的BeanDefinition进行修改
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {

            }
            mbd.postProcessed = true;
        }
    }

    // 这个主要和循环依赖有关,后续专门的章节来讲述,这里先不解释
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
//这里会组装bean对象,包含对属性赋值,还有BeanPostProcessor执行实例化后的方法
        populateBean(beanName, mbd, instanceWrapper);
//bean的初始化,这里主要包含BeanPostProcessor执行初始化前方法,bean自身的初始化init方法,BeanPostProcessor初始化后方法
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        
    }

    //省略......

    return exposedObject;
}

执行完这个方法后,spring的bean对象就创建好了,当然这个方法里面有很多细节的东西需要去理解和掌握,特别是很多BeanPostProcessor的功能作用,但本文主要是先了解下bean的整体流程,先不扣细节,有助于理解。

看完这几个方法源码,梳理下,大概的流程如下


bean的简单生命周期.png

相关文章

网友评论

      本文标题:spring bean的生命周期

      本文链接:https://www.haomeiwen.com/subject/quxtjktx.html