mybatis spring整合

SqlSessionFactoryBean

继承FactoryBean接口,表示该类为创建SqlSessionFactory的工厂类
继承InitializingBean接口,在创建对象实例填充属性后会执行初始化回调,调用afterPropertiesSet方法完成mybatis的初始化(创建Configuration、Environment、MappedStatement····)
继承ApplicationListener接口,监听ApplicationEvent事件,确保mappedStatements解析完成

public class SqlSessionFactoryBean
    implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
	// 创建者,用来创建SqlSessionFactory,全局唯一
	private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
	// 配置文件
	private Resource configLocation;
	// xml资源位置
	private Resource[] mapperLocations;
	// 连接源
	private DataSource dataSource;
}

MapperScannerConfigurer

mybatis中为mapper接口扫描生成代理类的配置类

继承BeanDefinitionRegistryPostProcessor接口,在初始化IOC容器时调用其postProcessBeanDefinitionRegistry方法
使用ClassPathMapperScanner扫描包中接口类,默认的include过滤器接受所有类,将包中接口类定义为BeanDifinition添加到当前beanFactory中
1.创建ScannedGenericBeanDefinition过滤掉不是接口的类metadata存放接口的原始信息,此时存在beanClass和resource
2.设置scope,处理注解来设置对应属性(Lazy、Primary、DependsOn、Role、Description),注册到BeanFactory中
3.设置BeanDifinition的属性,核心为设置beanClass为mapperFactoryBean(所有接口类都为该类型),配置sqlSessionFactory、sqlSessionTemplate属性值
 
继承InitializingBean接口,确保basePackage不为null

public class MapperScannerConfigurer
    implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
	// 扫描包位置
	private String basePackage;
	// 持有的SqlSessionFactory
	private SqlSessionFactory sqlSessionFactory;

	private SqlSessionTemplate sqlSessionTemplate;
	// SqlSessionFactory的Bean名称
	private String sqlSessionFactoryBeanName;

	private String sqlSessionTemplateBeanName;
	
	// SqlSession代理对象生成
	private Class<? extends MapperFactoryBean> mapperFactoryBeanClass;
}

MapperFactoryBean

继承结构

在这里插入图片描述

继承FactoryBean接口,生成代理Mapper对象,@AutoWired通过DefaultListableBeanFactory的resolveDependency方法解析,在findAutowireCandidates方法时调用了createInstance方法创建接口实例,并放入factoryBeanInstanceCache中
继承InitializingBean接口,确保Configuration类中mapperRegistry已经加载对应的Mapper接口
mapperInterface通过构造函数传入
通过传入SqlSessionFactory创建SqlSessionTemplate

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
  // 真实Mapper接口
  private Class<T> mapperInterface;
  // 是否将Mapper添加到配置
  private boolean addToConfig = true;
}

SqlSessionTemplate

通过SqlSessionInterceptor拦截,每次调用时生成一个DefaultsqlSession来执行方法,保证线程安全。

public class SqlSessionTemplate implements SqlSession, DisposableBean {
  // 工厂 required
  private final SqlSessionFactory sqlSessionFactory;
  // 执行器类型	required
  private final ExecutorType executorType;
  // sqlSession代理
  private final SqlSession sqlSessionProxy;
  
  // 构造方法
  public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator) {

    this.sqlSessionFactory = sqlSessionFactory;
    this.executorType = executorType;
    this.exceptionTranslator = exceptionTranslator;
	// 生成代理对象
    this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class }, new SqlSessionInterceptor());
  }
}  

// 代理方法
private class SqlSessionInterceptor implements InvocationHandler {
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	  // 通过事务同步管理器来获得sqlSession,如果未开启事务则每次获得新的sqlSession
	  SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
		  SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
	  try {
		// 新的sqlSession来处理
		Object result = method.invoke(sqlSession, args);
		// 未开启事务自动提交
		if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
		  // force commit even on non-dirty sessions because some databases require
		  // a commit/rollback before calling close()
		  sqlSession.commit(true);
		}
		return result;
	  } catch (Throwable t) {
		Throwable unwrapped = unwrapThrowable(t);
		if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
		  // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
		  closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
		  sqlSession = null;
		  Throwable translated = SqlSessionTemplate.this.exceptionTranslator
			  .translateExceptionIfPossible((PersistenceException) unwrapped);
		  if (translated != null) {
			unwrapped = translated;
		  }
		}
		throw unwrapped;
	  } finally {
	    // 关闭sqlSession
		if (sqlSession != null) {
		  closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
		}
	  }
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值