SpringMyBatis解析3-MapperFactoryBean


在使用mybatis的時候,我們獲取dao的方式一般是這樣:

SqlSession session=sessionFactory.openSession();  
PersonDao personDao=session.getMapper(PersonDao.class);  

但在我們在spring的測試用例中使用mybatis的時候是這樣使用的:

PersonDao personDao=(PersonDao) context.getBean("personDao");  

答案就在MapperFactoryBean這里。

Spring中獲取的名為personDao的bean,其實是與單獨使用MyBatis完成了一樣的功能,那么我們可以推斷,在bean的創建過程中一定是使用了MyBatis中的原生方法sqlSession.getMapper(PersonDao.class)進行了再一次封裝。結合配置文件,我們把分析目標轉向org.mybatis.Spring.mapper.MapperFactoryBean,初步推測其中的邏輯應該在此類中實現。查看的類層次結構圖MapperFactoryBean也實現了FactoryBean和InitializingBean接口。

MapperFactoryBean初始化

MapperFactoryBean繼承了SqlSessionDaoSupport,SqlSessionDaoSupport繼承DaoSupport,DaoSupport實現了InitializingBean接口,讓我們開看看它這接口的實現:

public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {  
    // Let abstract subclasses check their configuration.  
 checkDaoConfig();  
    // Let concrete implementations initialize themselves.  
    try {  
     //initDao()方法是模板方法,設計為留給子類做進一步邏輯處理。 initDao(); }
catch (Exception ex) { throw new BeanInitializationException("Initialization of DAO failed", ex); } }

該方法主要包含兩個功能,一個是調用checkDaoConfig()方法,一個是調用initDao方法。checkDaoConfig方法在DaoSupport是抽象方法,讓我看看它在MapperFactoryBean的實現:

@Override  
 protected void checkDaoConfig() {  
   super.checkDaoConfig();  
   notNull(this.mapperInterface, "Property 'mapperInterface' is required");  
   Configuration configuration = getSqlSession().getConfiguration();  
   if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {  
     try {  
       configuration.addMapper(this.mapperInterface);  
     } catch (Throwable t) {  
       logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", t);  
       throw new IllegalArgumentException(t);  
     } finally {  
       ErrorContext.instance().reset();  
     }  
   }  
 }  

該方法主要是檢查dao的配置,主要是檢驗sqlSessionFactory和mapperInterface屬性不能為空,以及檢測接口對於的映射文件是否存在,如果存在,那么就把它添加到configuration里面去,注冊mapper。

在上面的函數中,configuration.addMapper(this.mapperInterface)其實就是將PersonDao注冊到映射類型中,如果你可以保證這個接口一定存在對應的映射文件,那么其實這個驗證並沒有必要。但是,由於這個是我們自行決定的配置,無法保證這里配置的接口一定存在對應的映射文件,所以這里非常有必要進行驗證。在執行此代碼的時候,MyBatis會檢查嵌入的映射接口是否存在對應的映射文件,如果沒有回拋出異常,Spring正是在用這種方式來完成接口對應的映射文件存在性驗證。

獲取MapperFactoryBean的實例

public T getObject() throws Exception {  
  return getSqlSession().getMapper(this.mapperInterface);  
}  
在這里封裝了getMapper操作,返回接口的實例,怪不得在Spring中使用MyBatis不用管理sqlSession了。 所以對於上面的測試用例,Spring怎么封裝了MyBatis,如何把sqlSessionFactory和sqlSession隱藏了起來,又怎么方便的獲取dao接口實例,我們大概有了一個了解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM