• Spring源码阅读(三)


    上一讲我们谈到单例生产关键方法getSingleton。getSingleton方法由DefaultSingletonBeanRegistry类实现。我们的抽象工厂AbstractBeanFactory继承了FactoryBeanRegistrySupport,而FactoryBeanRegistrySupport则继承了DefaultSingletonBeanRegistry,AbstractBeanFactory注册实例的工作实际上由DefaultSingletonBeanRegistry实施,不过其中生产单例的操作还是回调了AbstractBeanFactory中的createBean方法。

    DefaultSingletonBeanRegistry类结构

    可以看到,DefaultSingletonBeanRegistry实现了

    (1)单例注册SingletonBeanRegistry

    (2)别名注册SimpleAliasRegistry

    同时,DefaultSingletonBeanRegistry需要传入ObjectFactory实现实例的创建,传入DisposableBean实现实例的销毁。

        /**
         * Return the (raw) singleton object registered under the given name,
         * creating and registering a new one if none registered yet.
         * 返回一个单例,不存在则创建并注册
         * @param beanName the name of the bean
         * @param singletonFactory the ObjectFactory to lazily create the singleton
         * 单例创建工厂
         * with, if necessary
         * @return the registered singleton object
         */
        public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "Bean name must not be null");
            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 (logger.isDebugEnabled()) {
                        logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                    }
                    // 单例创建前刷新状态
                    beforeSingletonCreation(beanName);
                    boolean newSingleton = false;
                    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = new LinkedHashSet<>();
                    }
                    // 调用单例创建工厂创建单例
                    try {
                        singletonObject = singletonFactory.getObject();
                        newSingleton = true;
                    }
                    catch (IllegalStateException ex) {
                        // Has the singleton object implicitly appeared in the meantime ->
                        // if yes, proceed with it since the exception indicates that state.
                        singletonObject = this.singletonObjects.get(beanName);
                        if (singletonObject == null) {
                            throw ex;
                        }
                    }
                    catch (BeanCreationException ex) {
                        if (recordSuppressedExceptions) {
                            for (Exception suppressedException : this.suppressedExceptions) {
                                ex.addRelatedCause(suppressedException);
                            }
                        }
                        throw ex;
                    }
                    finally {
                        if (recordSuppressedExceptions) {
                            this.suppressedExceptions = null;
                        }
                        // 单例创建后刷新状态
                        afterSingletonCreation(beanName);
                    }
                    // 单例注册
                    if (newSingleton) {
                        addSingleton(beanName, singletonObject);
                    }
                }
                return singletonObject;
            }
        }

    createBean方法我们在下一讲中研究。

  • 相关阅读:
    nagios安装配置
    Nagios:企业级系统监控方案
    使用Maven搭建Struts2+Spring3+Hibernate4的整合开发环境
    SecureCRT最佳配色方法+直接修改默认配置方法
    highcharts插件使用总结和开发中遇到的问题及解决办法
    关于Highcharts图表组件动态修改属性的方法(API)总结之Series
    Linux中环境变量文件及配置
    使用正则表达式匹配任意字符包括空格和换行符
    设置mysql远程连接root权限
    java读取文件夹下所有文件并替换文件每一行中指定的字符串
  • 原文地址:https://www.cnblogs.com/coshaho/p/7682310.html
Copyright © 2020-2023  润新知