mybatis的sqlSessionFactory的加载过程

栏目: 数据库 · 发布时间: 6年前

内容简介:使用过SSM的框架的都知道mybatis这个持久层框架,今天小编就来简单说说这个框架的核心工厂类sqlSessionFactory的加载过程,一般的SSM框架我们都会在spring的application.xml中引入如下的配置:<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property>

使用过SSM的框架的都知道mybatis这个持久层框架,今天小编就来简单说说这个框架的核心工厂类sqlSessionFactory的加载过程,一般的SSM框架我们都会在spring的application.xml中引入如下的配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource"></property>

<property name="configLocation" value="classpath:config/mybatis-config.xml"></property>

</bean>

其中的SqlSessionFactoryBean便是加载sqlSessionFactory的入口,首先我们来看看这个类的源代码:

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

private static final Log logger = LogFactory.getLog(SqlSessionFactoryBean.class);

private Resource configLocation;

private Resource[] mapperLocations;

private DataSource dataSource;

private TransactionFactory transactionFactory;

private Properties configurationProperties;

private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

private SqlSessionFactory sqlSessionFactory;

其中标红的两处,就是我们在application.xml中注入的两个属性,从源码中我们可以看出该类实现了InitializingBean接口,实现了其afterPropertiesSet()方法,

该方法是在当前bean的所有属性被初始化完成之后再执行,也就是其中的datasource和configurationProperties等属性,接下来我们看看这个方法主要干什么了?

public void afterPropertiesSet() throws Exception {

notNull(dataSource, "Property 'dataSource' is required");

notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");

this.sqlSessionFactory = buildSqlSessionFactory();

}

其中第5行很明显的buildSqlSessionFactory()方法初始化了sqlSessionFactory ,接下来我们看看这个方法的主要行为:

Configuration configuration;

XMLConfigBuilder xmlConfigBuilder = null;

if (this.configLocation != null) {

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

configuration = xmlConfigBuilder.getConfiguration();

} else {

if (logger.isDebugEnabled()) {

logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");

}

configuration = new Configuration();

configuration.setVariables(this.configurationProperties);

}

if (this.objectFactory != null) {

configuration.setObjectFactory(this.objectFactory);

}

if (this.objectWrapperFactory != null) {

configuration.setObjectWrapperFactory(this.objectWrapperFactory);

}

if (hasLength(this.typeAliasesPackage)) {

String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,

ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

for (String packageToScan : typeAliasPackageArray) {

configuration.getTypeAliasRegistry().registerAliases(packageToScan,

typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);

if (logger.isDebugEnabled()) {

logger.debug("Scanned package: '" + packageToScan + "' for aliases");

}

}

}

if (!isEmpty(this.typeAliases)) {

for (Class<?> typeAlias : this.typeAliases) {

configuration.getTypeAliasRegistry().registerAlias(typeAlias);

if (logger.isDebugEnabled()) {

logger.debug("Registered type alias: '" + typeAlias + "'");

}

}

}

if (!isEmpty(this.plugins)) {

for (Interceptor plugin : this.plugins) {

configuration.addInterceptor(plugin);

if (logger.isDebugEnabled()) {

logger.debug("Registered plugin: '" + plugin + "'");

}

}

}

if (hasLength(this.typeHandlersPackage)) {

String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,

ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

for (String packageToScan : typeHandlersPackageArray) {

configuration.getTypeHandlerRegistry().register(packageToScan);

if (logger.isDebugEnabled()) {

logger.debug("Scanned package: '" + packageToScan + "' for type handlers");

}

}

}

if (!isEmpty(this.typeHandlers)) {

for (TypeHandler<?> typeHandler : this.typeHandlers) {

configuration.getTypeHandlerRegistry().register(typeHandler);

if (logger.isDebugEnabled()) {

logger.debug("Registered type handler: '" + typeHandler + "'");

}

}

}

if (xmlConfigBuilder != null) {

try {

xmlConfigBuilder.parse();

if (logger.isDebugEnabled()) {

logger.debug("Parsed configuration file: '" + this.configLocation + "'");

}

} catch (Exception ex) {

throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);

} finally {

ErrorContext.instance().reset();

}

}

if (this.transactionFactory == null) {

this.transactionFactory = new SpringManagedTransactionFactory();

}

Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);

configuration.setEnvironment(environment);

if (this.databaseIdProvider != null) {

try {

configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));

} catch (SQLException e) {

throw new NestedIOException("Failed getting a databaseId", e);

}

}

if (!isEmpty(this.mapperLocations)) {

for (Resource mapperLocation : this.mapperLocations) {

if (mapperLocation == null) {

continue;

}

try {

XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),

configuration, mapperLocation.toString(), configuration.getSqlFragments());

xmlMapperBuilder.parse();

} catch (Exception e) {

throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);

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

}

}

该方法主要就是设置configuration参数,首先是从mybatis-config.xml中获取对应的配置信息,然后再从spring的注入属性中获取所有的配置信息,从后调用

sqlSessionFactoryBuilder.build(configuration)方法获取sqlSessionFactory的实例。

由于整个加载过程没有过多的难点,所以就介绍到这里,感兴趣的朋友可以自己去源码,了解更多知识。

Linux公社的RSS地址: https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-08/153451.htm


以上所述就是小编给大家介绍的《mybatis的sqlSessionFactory的加载过程》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Rust编程之道

Rust编程之道

张汉东 / 电子工业出版社 / 2019-1 / 128

Rust 是一门利用现代化的类型系统,有机地融合了内存管理、所有权语义和混合编程范式的编程语言。它不仅能科学地保证程序的正确性,还能保证内存安全和线程安全。同时,还有能与C/C++语言媲美的性能,以及能和动态语言媲美的开发效率。 《Rust编程之道》并非对语法内容进行简单罗列讲解,而是从四个维度深入全面且通透地介绍了Rust 语言。从设计哲学出发,探索Rust 语言的内在一致性;从源码分析入......一起来看看 《Rust编程之道》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具