zoukankan      html  css  js  c++  java
  • 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接口实例,我们大概有了一个了解。
  • 相关阅读:
    Nginx使用GeoIP模块来限制地区访问
    CenTOS7使用ACL控制目录权限,只给某个用户访问特定目录
    CentOS配置服务开机自启
    设置普通用户输入sudo,免密进入root账户
    Centos安装git并配置ssh
    ThreadLocal线程隔离
    Spring cloud 超时配置总结
    Hystrix超时测试
    mysql limit分页查询效率比拼
    linux CPU100%异常排查
  • 原文地址:https://www.cnblogs.com/wade-luffy/p/6093435.html
Copyright © 2011-2022 走看看