1. 首先了解一下mybatis,包含核心jar ,以及spring相關jar.
<!-- Mybatis相關組件 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency>
- 系列的文章也是mybatis 3.3.0和mybatis-spring1.2.3分析
- mybatis jar包中只要包含mybaits的核心業務sqlsession,sqlsessionFactory,configuration
- mybatis-spring 包中只要是和spring的相關集成,sqlSessionFactoryBean、transaction
2. 加載mybatis
本文以spring中加載mybatis為參考,由一下代碼加載mybatis
<!-- 配置集成Mybatis --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:/config/SQLMapConfig.xml" /> <property name="mapperLocations" value="classpath*:com/chihiro/*/**/infra/mybatis/*Mapper.xml" /> </bean>
- sqlSessionFactory接口(mybatis包核心接口)
a、接口中有如下方法。子類中含有所有方法的實現
public interface SqlSessionFactory { SqlSession openSession(); SqlSession openSession(boolean autoCommit); SqlSession openSession(Connection connection); SqlSession openSession(TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType); SqlSession openSession(ExecutorType execType, boolean autoCommit); SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType, Connection connection); Configuration getConfiguration(); }
b、接口的實現類,由sqlSessionFactoryBean產生的是默認的SqlSessionFactory(DefaultSqlSessionFactory)
- sqlSessionFactoryBean(mybatis-spring包下面的創建工廠的Bean,由spring 加載初始化)
a、從上述mybais的加載,可以看到,構造sqlSessionFactoryBean之后給了默認的屬性值,dataSource,configLocation,mapper
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; //SqlSessionFactory 構造的協助類 private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); private SqlSessionFactory sqlSessionFactory; //創建sqlSessionFactory的方法體 protected SqlSessionFactory buildSqlSessionFactory() throws IOException { 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); } ... return this.sqlSessionFactoryBuilder.build(configuration); }ss @Override public void afterPropertiesSet() throws Exception { notNull(dataSource, "Property 'dataSource' is required"); notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required"); //調用方法創建sqlSessionFactory this.sqlSessionFactory = buildSqlSessionFactory(); } @Override public void onApplicationEvent(ApplicationEvent event) { if (failFast && event instanceof ContextRefreshedEvent) { // fail-fast -> check all statements are completed this.sqlSessionFactory.getConfiguration().getMappedStatementNames(); } } }
- 實現3個相關接口的作用
FactoryBean接口:實現了該接口的類,在調用getBean(獲取bean對象)的時候會返回該工廠返回的實例對象,也就是再調一次getObject方法返回工廠的實例。
InitializingBean接口:實現了這個接口,那么當bean初始化的時候,spring就會調用該接口的實現類的afterPropertiesSet方法,去實現當spring初始化該Bean的時候所需要的邏輯。
ApplicationListener接口:實現了該接口,如果注冊了該監聽的話,那么就可以了監聽到Spring的一些事件,然后做相應的處理
2.在bean初始化之后,可以看見,回調方法afterPropertiesSet,在里面構造configuration對象。以及產生sqlSession
Configuration類:可以發現配置中讀取configuration。(核心配置,關聯mybatis整個生命周期)
xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties); configuration = xmlConfigBuilder.getConfiguration();
3.由sqlSessionFactoryBuild 構造sqlSessionFactory
public class SqlSessionFactoryBuilder { public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); } }
4. 建設者模式
生產sqlSessionFacoty 使用了建設者模式(Builder)。其構造過程主要注入了Configuration的實例對象,sqlSessionFactoryBuilder 扮演具體的建造者,configuration類主要負責建造細節的工作,sqlSessionFactory則是建造出來的產品
- 總結