SSM中sqlsessionfactorybean的加载过程

    <context:component-scan base-package="test.com.bytedance" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <context:property-placeholder location="classpath:/conf/jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!--整合mybatis-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:/conf/mybatis-config.xml"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:/conf/mybatis/mappers/*.xml"/>
    </bean>

首先需要知道类的作用。SqlSessionFactoryBean 类的作用就是通过加载器读取mybatis-config.xml和applicationContext.xml生成 SqlSessionFactory。以上是spring的配置文件,启动tomcat后,会首先创建一个sqlsessionfactorybean实例,并对其

private Resource configLocation
private DataSource dataSource
private Resource[] mapperLocations

等属性进行填充。创建 SqlSessionFactory 的过程就是不断的读取配置文件中的属性,然后 set 进入 Configuration 中。通过getobject获取SqlSessionFactory的实例。

果然spring先调用factorybean接口的getbean方法,获取了一个SqlSessionFactoryBean对象,又调用了FactoryBean接口的getObject方法

此外留意一下其属性里还有两个核心属性,这是构造SqlSessionFactory的关键

private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder()
private SqlSessionFactory sqlSessionFactory

下面按顺序分析一下

获取SqlSessionFactoryBean对象,并执行构造函数,然后填充属性

    public SqlSessionFactoryBean() {
    }

    public void setConfigLocation(Resource configLocation) {
        this.configLocation = configLocation;
    }

    public void setMapperLocations(Resource... mapperLocations) {
        this.mapperLocations = mapperLocations;
    }
    
    public void setDataSource(DataSource dataSource) {
        if (dataSource instanceof TransactionAwareDataSourceProxy) {
            this.dataSource = ((TransactionAwareDataSourceProxy)dataSource).getTargetDataSource();
        } else {
            this.dataSource = dataSource;
        }

    }

执行完属性的初始化后,调用getObject方法

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

        return this.sqlSessionFactory;
    }

此时factory还未创建,所以会执行afterPropertiesSet方法

    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();
    }

接着方法末尾执行buildSqlSessionFactory方法

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
    //此处省去一万个处理,然后我们关注核心部分
    //省略
    //省略
    
    //绑定mapper
    if (this.mapperLocations != null) {
            if (this.mapperLocations.length == 0) {
                LOGGER.warn(() -> {
                    return "Property 'mapperLocations' was specified but matching resources are not found.";
                });
            } else {
                Resource[] var3 = this.mapperLocations;
                int var4 = var3.length;

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

                        LOGGER.debug(() -> {
                            return "Parsed mapper file: '" + mapperLocation + "'";
                        });
                    }
                }
            }
        }


    return this.sqlSessionFactoryBuilder.build(targetConfiguration);
}

你会欣喜若狂的发现,终于用我们已经实例化的SqlSessionFactoryBuilder创建并返回了我们望眼欲穿的SqlSessionFactory(此处应该有掌声,第二篇文章,写的不好,见谅)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值