Spring bean的生命周期

1. 实例化sping容器

具体的有三种实现方式

ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:***");
ApplicationContext ac = new AnnotationConfigApplicationContext(***.class);
ApplicationContext ac = new FileSystemXmlApplicationContext("***");

如果我们使用的是上诉第二种实例化spring容器的方式则会先在spring容器中对该配置类进行注册,在通过配置类去进行扫描

2. 如果是xml则是在obtainFreshBeanFactory方法生成beanFactory对象,生成BeanDefinition对象,并装载进入beanDefinitionMap中

工厂类为DefaultListableBeanFactory

3. 扫描符合springbean规则的class集合并将这些class其封装成beanDefinition对象置入beanDefinitionMap中

//使用的是refresh()方法下的该方法
//beanFactory中有一个属性beanDefinitionMap
//调用有点繁复,各位可以自行debug窥探一二
invokeBeanFactoryPostProcessors(beanFactory);

beanDefinitionMap的组成为<类名,beanDefinition>

3、遍历beanDefinitionMap并对其beanDefinition进行验证

    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }
//获取beanDefinitionMap中beanName集合
        List beanNames = new ArrayList(this.beanDefinitionNames);
//遍历
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
//调用getBean
                    getBean(beanName);
                }
            }
        }


        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction() {
                        @Override
                        public Object run() {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

 
 

4.做一些先驱操作,如dependsOn

    protected  T doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

//后续循环依赖会用上
//先去单例池中找
//没有查看是否是处于创建状态中
//详见代码块..
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
...
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else {
            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                String[] dependsOn = mbd.getDependsOn();
//检测是否有dependsOn依赖,有的话先加载
                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);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
//销毁
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
...
        return (T) bean;
    }
 
 

通过以上流程步骤进入到创建单例bean的过程creatBean();

  • public Object getSingleton()

    public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(beanName, "'beanName' must not be null");
        Map var3 = this.singletonObjects;
//上锁
        synchronized(this.singletonObjects) {
//去单例缓存池里尝试获取该对象,若能获取到,则无须创建,返回即可
            Object singletonObject = this.singletonObjects.get(beanName);
//需要创建
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
            /* 
             * 将 beanName 添加到 singletonsCurrentlyInCreation 集合中,
             * 用于表明 beanName 对应的 bean 正在创建中
             * 可以解决循环依赖问题
             */
                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {
 // 通过 getObject 方法调用 createBean 方法创建 bean 实例
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } 

                    throw ex;
                } finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
 // 将 beanName 从 singletonsCurrentlyInCreation 移除
                    this.afterSingletonCreation(beanName);
                }
//如果创建成功
                if (newSingleton) {
                /* 
                 * 将  键值对添加到 singletonObjects 集合中,
                 * 并从其他集合(比如 earlySingletonObjects)中移除 singletonObject 记录
                 */
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject != NULL_OBJECT ? singletonObject : null;
        }
    }

步骤
1.先从 singletonObjects 集合获取 bean 实例,若不为空,则直接返回
2.若为空,进入创建 bean 实例阶段。先将 beanName 添加到 singletonsCurrentlyInCreation
3.通过 getObject 方法调用 createBean 方法创建 bean 实例
4.将 beanName 从 singletonsCurrentlyInCreation 集合中移除
5.将 映射缓存到 singletonObjects 集合中

5. 创建bean

  • createBean()

    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
// 解析 bean 的类型
        Class resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 在 bean 初始化前应用后置处理,如果后置处理返回的 bean 不为空,则直接返回
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
   // 调用 doCreateBean 创建 bean
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

  • doCreateBean()真正的创建bean
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
//实例化
//反射创建对象,这里是被包裹住了
//注意这里创建的是java 对象,不是bean,且此时里面没有属性
//见下面代码
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

    /*
     * earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露
     * 单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下:
     *   条件1:mbd.isSingleton() - 表示 bean 是否是单例类型
     *   条件2:allowCircularReferences - 是否允许循环依赖
     *   条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中
     * 
     * earlySingletonExposure = 条件1 && 条件2 && 条件3 
     *                        = 单例 && 是否允许循环依赖 && 是否存于创建状态中。
     *是否允许循环依赖,允许则暴露一个工厂
     */
        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, new ObjectFactory() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
//填充属性
//注意这里传入的是beanName,beanDefinition,和一个实例
//意思就是在beanDefinition中将对象置入,在根据beanName将beanDefinition置入BeanDefinitionMap中
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
//初始化
//见下面代码
                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);
            }
        }

        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 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 " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }
 
 

6. createBeanInstance() 推断构造方法并使用该构造方法构建对象

//推断构造方法
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
//构建对象
            return autowireConstructor(beanName, mbd, ctors, args);
        }

7. bean初始化

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
//执行对象的部分aware
//1. BeanNameAware
//2. BeanClassLoaderAware
//3. BeanFactoryAware
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
//执行部分aware方法 anno lifecycle init callback
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
//接口版 lifecycle init callback
            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()) {
//aop
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

 
 

二、讲一讲细节

循环依赖

问题:

假如有两个类A,B循环依赖
根据bean的生命周期,在创建A的bean时,扫描到A时实例化一个A实例,然后填充属性,此时发现有没有属性B的bean于是去创建B的bean,同理,创建B时也会产生同样的问题,这就是循环依赖问题

那么spring是如何解决这个问题的呢?

答案是singletonsCurrentlyInCreation集合和spring三级缓存
1.singletonsCurrentlyInCreation集合
以下为顺序调用:

  • (1) 在doGetBean()方法下一开始就查看是否有该bean
Object sharedInstance = getSingleton(beanName);
->
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//一开始在singletonObjects搜寻
        Object singletonObject = this.singletonObjects.get(beanName);
//没找到则在singletonsCurrentlyInCreation集合中搜寻
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
//在earlySingletonObjects Map中搜寻
//一级缓存
                singletonObject = this.earlySingletonObjects.get(beanName);
//还没有的情况下
                if (singletonObject == null && allowEarlyReference) {
//生产工厂去生产一个该bean
                    ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
//二级缓存
                        singletonObject = singletonFactory.getObject();
//存入earlySingletonObjects Map
//三级缓存
                        this.earlySingletonObjects.put(beanName, singletonObject);
//将该该类从工厂中删除
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
  • (2)在doGetBean()方法下调用的getSingleton(String beanName, ObjectFactory singletonFactory)下有一个:
    beforeSingletonCreation(beanName)方法:
this.singletonsCurrentlyInCreation.add(beanName)

将该对象的名称加入singletonsCurrentlyInCreation集合

这两个层面的内容应该很容易看懂,(1)执行在(2)前,所以在循环创建的过程中,第二次创建就能进入getSingleton()直接进行bean创建
  • (3)三级缓存

  • 一级缓存 singletonObjects Map
    创建bean成功就会进入一级缓存

  • 二级缓存 singletonFactory Map

  • 三级缓存 earlySingletonObjects
    如果支持循环依赖才会有三级缓存
    循环依赖具体由allowCircularReferences属性来决定,若支持,则直接在二级缓存中创建该工厂

    protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }
为什么会有三级缓存呢?按照道理而言只需要有二级缓存生产对象就可以了啊?

答:因为工厂生产对象需要花费时间,而我们只需要工厂生产完成以后将对象放入三级缓存,后续再需要直接从二级缓存中拿就可以了。

上述创建工厂代码块(3)中有一个清除三级缓存是因为产生了新工厂,所以需要清空原先工厂生产的对象
上述代码(1)中清除掉了生产对应对象的工厂,是因为该工厂只需要生产一个对象放入三级缓存中,后续不需要用到该工厂了,所以将他清除GC掉。

你可能感兴趣的:(Spring bean的生命周期)