sqlSessionFactory创建

sqlSessionFactory创建前言分析上篇文章的整合的配置文件,我们可以知道配置的bean是成树状结构的,而在树的最顶层是类型为org.mybatis.Spring.SqlSessionFactoryBean的bean,它将其他相关的bean组装在了一起,那么我们的分析就从此类开始。sqlSessionFactory创建对于配置文件的读取,Spring是通过org.mybatis.Spring.SqlSessi…

大家好,又见面了,我是你们的朋友全栈君。

 前言

分析上篇文章的整合的配置文件,我们可以知道配置的bean是成树状结构的,而在树的最顶层是类型为org.mybatis.Spring.SqlSessionFactoryBean的bean,它将其他相关的bean组装在了一起,那么我们的分析就从此类开始。

sqlSessionFactory创建

 对于配置文件的读取,Spring是通过org.mybatis.Spring.SqlSessionFactoryBean封装了MyBatis中的实现。首先来看一下这个类的类图:

sqlSessionFactory创建

根据上图对两个感兴趣的接口FactoryBean和InitializingBean。

  ❤ InitializingBean:实现此接口的bean会在初始化时调用其afterPropertiesSet方法来进行bean的逻辑初始化。

  ❤ FactoryBean:一旦某个bean实现此接口,那么通过getBean方法获取bean时其实是获取此类的getObject返回的实例。

1.sqlSessionFactoryBean的初始化

 查看org.mybatis.Spring.SqlSessionFactoryBean类型的bean在初始化时做了哪些逻辑实现。

public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.dataSource, "Property 'dataSource' is required");
        Assert.notNull(this.sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
        Assert.state(this.configuration == null && this.configLocation == null || this.configuration == null || this.configLocation == null, "Property 'configuration' and 'configLocation' can not specified with together");
        this.sqlSessionFactory = this.buildSqlSessionFactory();
    }

很显然,此函数的主要目的是对于sqlSessionFactory的初始化,sqlSessionFactory是所有MyBatis功能的基础。

protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
        XMLConfigBuilder xmlConfigBuilder = null;
        Configuration configuration;
        if (this.configuration != null) {
            configuration = this.configuration;
            if (configuration.getVariables() == null) {
                configuration.setVariables(this.configurationProperties);
            } else if (this.configurationProperties != null) {
                configuration.getVariables().putAll(this.configurationProperties);
            }
        } else if (this.configLocation != null) {
            xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), (String)null, this.configurationProperties);
            configuration = xmlConfigBuilder.getConfiguration();
        } else {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");
            }

            configuration = new Configuration();
            if (this.configurationProperties != null) {
                configuration.setVariables(this.configurationProperties);
            }
        }

        if (this.objectFactory != null) {
            configuration.setObjectFactory(this.objectFactory);
        }

        if (this.objectWrapperFactory != null) {
            configuration.setObjectWrapperFactory(this.objectWrapperFactory);
        }

        if (this.vfs != null) {
            configuration.setVfsImpl(this.vfs);
        }

        String[] typeHandlersPackageArray;
        String[] var4;
        int var5;
        int var6;
        String packageToScan;
        if (StringUtils.hasLength(this.typeAliasesPackage)) {
            typeHandlersPackageArray = StringUtils.tokenizeToStringArray(this.typeAliasesPackage, ",; \t\n");
            var4 = typeHandlersPackageArray;
            var5 = typeHandlersPackageArray.length;

            for(var6 = 0; var6 < var5; ++var6) {
                packageToScan = var4[var6];
                configuration.getTypeAliasRegistry().registerAliases(packageToScan, this.typeAliasesSuperType == null ? Object.class : this.typeAliasesSuperType);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Scanned package: '" + packageToScan + "' for aliases");
                }
            }
        }

        int var27;
        if (!ObjectUtils.isEmpty(this.typeAliases)) {
            Class[] var25 = this.typeAliases;
            var27 = var25.length;

            for(var5 = 0; var5 < var27; ++var5) {
                Class<?> typeAlias = var25[var5];
                configuration.getTypeAliasRegistry().registerAlias(typeAlias);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Registered type alias: '" + typeAlias + "'");
                }
            }
        }

        if (!ObjectUtils.isEmpty(this.plugins)) {
            Interceptor[] var26 = this.plugins;
            var27 = var26.length;

            for(var5 = 0; var5 < var27; ++var5) {
                Interceptor plugin = var26[var5];
                configuration.addInterceptor(plugin);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Registered plugin: '" + plugin + "'");
                }
            }
        }

        if (StringUtils.hasLength(this.typeHandlersPackage)) {
            typeHandlersPackageArray = StringUtils.tokenizeToStringArray(this.typeHandlersPackage, ",; \t\n");
            var4 = typeHandlersPackageArray;
            var5 = typeHandlersPackageArray.length;

            for(var6 = 0; var6 < var5; ++var6) {
                packageToScan = var4[var6];
                configuration.getTypeHandlerRegistry().register(packageToScan);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Scanned package: '" + packageToScan + "' for type handlers");
                }
            }
        }

        if (!ObjectUtils.isEmpty(this.typeHandlers)) {
            TypeHandler[] var28 = this.typeHandlers;
            var27 = var28.length;

            for(var5 = 0; var5 < var27; ++var5) {
                TypeHandler<?> typeHandler = var28[var5];
                configuration.getTypeHandlerRegistry().register(typeHandler);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Registered type handler: '" + typeHandler + "'");
                }
            }
        }

        if (this.databaseIdProvider != null) {
            try {
                configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
            } catch (SQLException var24) {
                throw new NestedIOException("Failed getting a databaseId", var24);
            }
        }

        if (this.cache != null) {
            configuration.addCache(this.cache);
        }

        if (xmlConfigBuilder != null) {
            try {
                xmlConfigBuilder.parse();
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Parsed configuration file: '" + this.configLocation + "'");
                }
            } catch (Exception var22) {
                throw new NestedIOException("Failed to parse config resource: " + this.configLocation, var22);
            } finally {
                ErrorContext.instance().reset();
            }
        }

        if (this.transactionFactory == null) {
            this.transactionFactory = new SpringManagedTransactionFactory();
        }

        configuration.setEnvironment(new Environment(this.environment, this.transactionFactory, this.dataSource));
        if (!ObjectUtils.isEmpty(this.mapperLocations)) {
            Resource[] var29 = this.mapperLocations;
            var27 = var29.length;

            for(var5 = 0; var5 < var27; ++var5) {
                Resource mapperLocation = var29[var5];
                if (mapperLocation != null) {
                    try {
                        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(), configuration, mapperLocation.toString(), configuration.getSqlFragments());
                        xmlMapperBuilder.parse();
                    } catch (Exception var20) {
                        throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", var20);
                    } finally {
                        ErrorContext.instance().reset();
                    }

                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Parsed mapper file: '" + mapperLocation + "'");
                    }
                }
            }
        } else if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
        }

        return this.sqlSessionFactoryBuilder.build(configuration);
    }

从函数中可以看到,尽管我们还是习惯于将MyBatis的配置和Spring的配置独立出来,但是,这并不代表Spring中的配置不支持直接配置。也就是说,在上篇文章的示例中,完全裤取消配置中的configLocation属性,而把其中的属性直接写在sqlSessionFactoryBean中。

从这个函数中还可以得知,配置文件还可以支持其他多种属性的配置,如configLocation、objectFactory、objectWrapperFactory、typeAliasesPackage、typeAliases、typeHandlersPackage、plugins、typeHandlers、transactionFactory、databaseIdProvider、mapperLocations。

其实,如果只按照常用的配置,那么我们只需要在函数最开始按照如下方式处理configLocation:

   xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(),null,this.configurationProperties);
    configuration = xmlConfigBuilder.getConfiguration();

 根据configLocation构造XMLConfigBuilder并进行解析,但是,为了体现Spring更强大的兼容性,Spring还整合了MyBatis中其他属性的注入,并通过实例configuration来承载每一步所获取的信息并最终使用sqlSessionFactoryBuilder实例根据解析到的configuration创建sqlSessionFactory实例。

2.获取SqlSessionFactoryBean实例

 由于sqlSessionFactoryBean实现了FactoryBean接口,所以当通过getBean方法获取对应实例时,其实是获取该类的getObject函数返回的实例,也就是获得初始化后的sqlSessionFactory属性。

public SqlSessionFactory getObject() throws Exception {
        if (this.sqlSessionFactory == null) {
            this.afterPropertiesSet();
        }

        return this.sqlSessionFactory;
    }

 参考:《Spring源码深度解析》 郝佳 编著: 

转载于:https://www.cnblogs.com/Joe-Go/p/10255301.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140666.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ieda激活不成功解决方法

    idea激活失效方法,idea激活码,IDEA激活码,idea序列号

    2022年3月13日
    118
  • 数据结构:树

    数据结构:树

    2021年9月26日
    63
  • 红帽子虚拟机安装教程_红帽子联网后怎么安装gcc

    红帽子虚拟机安装教程_红帽子联网后怎么安装gcc在WindowsXP中安装虚拟机VMware的方法跟普通软件基本一致,需要填入注册密钥.安装完成以后就可以安装红帽子企业版5操作系统了,首先需要新建一台虚拟的计算机,为其分配内存,硬盘空间,CPU等信息,然后选择启动的位置,是硬盘中的ISO文件还是光驱中的启动,然后就可以启动虚拟机进行安装了.在安装红帽子企业版时选择定制安装,作为初学者可以选择把所有的东西都安装上,这…

    2025年11月15日
    8
  • rider激活码-激活码分享

    (rider激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlKU…

    2022年3月22日
    574
  • 开关稳压DC—DC降压电路简介

    开关稳压DC—DC降压电路简介  在做数字压力开关项目时,电源输入要求是12V~24V±10%,系统内需要5V和3.3V的电源,这时提供了三个方案从中选择,方案一:使用24V-5V和5V-3.3V的LDO线性稳压芯片。方案二:使用24V-12V,12V-5V,5V-3.3V种LDO线性稳压芯片。方案三:使用24V-5V开关稳压芯片和5V-3.3V的线性稳压芯片。  最后考虑决定使用方案三,方案一中24V-5V的线性稳压芯…

    2022年6月20日
    38
  • 事业单位图形推理1000题及答案_小学生图形推理题

    事业单位图形推理1000题及答案_小学生图形推理题  2020年事业单位联考:《职测》判断推理神预测!   经过几个月的紧张备考,广大考生终于在今天走上了“战场”。经过小时的奋笔疾书,2020年下半年事业单位联考职业能力测试于今天上午拉下帷幕。根据学员的惊喜反馈,我们发现华图教育又双叒叕预测中题目了!!!   通过考生们对题目的回忆,华图教育惊喜地发现有4个考点跟我们考前给学员预测的大致相同!下面我们就一起来简单看一下:   一…

    2025年8月27日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号