Mybatis系列十:创建SqlSession应用Plugin

一、DefaultSqlSessionFactory

SqlSessionFactory默认实现是DefaultSqlSessionFactory,提供了许多openSession重载方法,用于创建SqlSession。

 

1.1 根据DataSource创建SqlSession

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {

   Transaction tx = null;

   try {

     final Environment environment = configuration.getEnvironment();

     final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

     tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);

     final Executor executor = configuration.newExecutor(tx, execType);

     return new DefaultSqlSession(configuration, executor, autoCommit);

   } catch (Exception e) {

// 可能获取了连接,所以让我们调用close方法

     closeTransaction(tx);

     throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);

   } finally {

     ErrorContext.instance().reset();

   }

 }

 

1.2 根据Connection创建SqlSession

 private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {

   try {

     boolean autoCommit;

     try {

       autoCommit = connection.getAutoCommit();

     } catch (SQLException e) {

       // Failover to true, as most poor drivers

       // or databases won't support transactions

       autoCommit = true;

     }      

     final Environment environment = configuration.getEnvironment();

     final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

     final Transaction tx = transactionFactory.newTransaction(connection);

     final Executor executor = configuration.newExecutor(tx, execType);

     return new DefaultSqlSession(configuration, executor, autoCommit);

   } catch (Exception e) {

     throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);

   } finally {

     ErrorContext.instance().reset();

   }

 }

 

1.3 获取TransactionFactory

// 未配置默认是ManagedTransactionFactory

private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {

   if (environment == null || environment.getTransactionFactory() == null) {

     return new ManagedTransactionFactory();

   }

   return environment.getTransactionFactory();

 }

 

1.4 关闭Transaction

 private void closeTransaction(Transaction tx) {

   if (tx != null) {

     try {

       tx.close();

     } catch (SQLException ignore) {

       // Intentionally ignore. Prefer previous error.

     }

   }

 }

 

二、TransactionFactory

2.1 类图

 

2.2 JdbcTransactionFactory

2.2.1 根据Connection创建Transaction

public Transaction newTransaction(Connection conn) {

   return new JdbcTransaction(conn);

 }

 

 2.2.2 根据DataSource创建Transaction

public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {

   return new JdbcTransaction(ds, level, autoCommit);

 }

 

2.3 ManagedTransactionFactory

ManagedTransaction不支持commit、rollback。

2.3.1 根据Connection创建Transaction

public Transaction newTransaction(Connection conn) {

   return new ManagedTransaction(conn, closeConnection);

 }

 

2.3.2 根据DataSource创建Transaction

public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {

   // 静默忽略自动提交和隔离级别,因为托管事务完全由外部管理器控制。 它被默默地忽略,以使代码在托管配置和非托管配置之间保持可移植性。

   return new ManagedTransaction(ds, level, closeConnection);

 }

 

三、Configuration

3.1 创建Executor并应用Interceptor

public Executor newExecutor(Transaction transaction) {

   // defaultExecutorType默认是ExecutorType.SIMPLE

   return newExecutor(transaction, defaultExecutorType);

 }

 

// 默认创建SimpleExecutor,如果开启缓存则使用CachingExecutor装饰

 public Executor newExecutor(Transaction transaction, ExecutorType executorType) {

   executorType = executorType == null ? defaultExecutorType : executorType;

   executorType = executorType == null ? ExecutorType.SIMPLE : executorType;

   Executor executor;

   // 默认创建SimpleExecutor

   if (ExecutorType.BATCH == executorType) {

     executor = new BatchExecutor(this, transaction);

   } else if (ExecutorType.REUSE == executorType) {

     executor = new ReuseExecutor(this, transaction);

   } else {

     executor = new SimpleExecutor(this, transaction);

   }

   // 如果开启缓存则使用CachingExecutor装饰

   if (cacheEnabled) {

     executor = new CachingExecutor(executor);

   }

   // 应用Interceptor

   executor = (Executor) interceptorChain.pluginAll(executor);

   return executor;

 }

 

3.2 ParameterHandler应用Interceptor

public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {

   ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);

   parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);

   return parameterHandler;

 }

 

3.3 ResultSetHandler应用Interceptor

 public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,

     ResultHandler resultHandler, BoundSql boundSql) {

   ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);

   resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);

   return resultSetHandler;

 }

 

3.4 StatementHandler应用Interceptor

 public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {

   StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);

   statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);

   return statementHandler;

 }

 

四、插件

4.1 InterceptorChain

4.1.1 应用插件

public Object pluginAll(Object target) {

   for (Interceptor interceptor : interceptors) {

// 创建代理对象,应用Intercept增强

     target = interceptor.plugin(target);

   }

   return target;

 }

 

4.2 Interceptor

4.2.1 调用目标方法前处理

Object intercept(Invocation invocation) throws Throwable;

 

4.2.2 根据拦截器创建目标对象代理

借助Plugin创建代理对象

Object plugin(Object target);

 

4.2.3 配置属性

void setProperties(Properties properties);

 

4.3 Plugin

4.3.1 根据Interceptor创建代理对象

public static Object wrap(Object target, Interceptor interceptor) {

   // 获取拦截器拦截的目标方法

   Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);

   Class<?> type = target.getClass();

   // 获取拦截的目标方法接口

   Class<?>[] interfaces = getAllInterfaces(type, signatureMap);

   if (interfaces.length > 0) {

     return Proxy.newProxyInstance(

         type.getClassLoader(),

         interfaces,

         new Plugin(target, interceptor, signatureMap));

   }

   return target;

 }

 

4.3.2 Interceptor拦截目标方法

 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

   try {

     Set<Method> methods = signatureMap.get(method.getDeclaringClass());

     if (methods != null && methods.contains(method)) {

       return interceptor.intercept(new Invocation(target, method, args));

     }

     return method.invoke(target, args);

   } catch (Exception e) {

     throw ExceptionUtil.unwrapThrowable(e);

   }

 }

 

4.3.3 根据Interceptor上的@Intercepts注解获取拦截的方法

 private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {

   // 获取所有的@Intercepts注解

   Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);

   if (interceptsAnnotation == null) {

     throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());      

   }

   Signature[] sigs = interceptsAnnotation.value();

   Map<Class<?>, Set<Method>> signatureMap = new HashMap<Class<?>, Set<Method>>();

   for (Signature sig : sigs) {

     Set<Method> methods = signatureMap.get(sig.type());

     if (methods == null) {

       methods = new HashSet<Method>();

       signatureMap.put(sig.type(), methods);

     }

     try {

       Method method = sig.type().getMethod(sig.method(), sig.args());

       methods.add(method);

     } catch (NoSuchMethodException e) {

       throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);

     }

   }

   return signatureMap;

 }

 

4.3.4 根据拦截方法获取拦截方法所属接口

 private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) {

   Set<Class<?>> interfaces = new HashSet<Class<?>>();

   while (type != null) {

     for (Class<?> c : type.getInterfaces()) {

       if (signatureMap.containsKey(c)) {

         interfaces.add(c);

       }

     }

     type = type.getSuperclass();

   }

   return interfaces.toArray(new Class<?>[interfaces.size()]);

 }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值