原 MyBatis源码阅读——装饰器模式在MyBatis中的应用

Executor

首先我们看下Executor,打开MyBatis的源码org.apache.ibatis.session.Configuration

  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    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);
    }
    //如果开启了二级缓存则装饰原先的Executor
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

 

这里写图片描述
CachingExecutor (装饰器的具体实现对象)

public class CachingExecutor implements Executor {
    //持有组件对象
  private Executor delegate;
  private TransactionalCacheManager tcm = new TransactionalCacheManager();
    //构造方法,传入组件对象
  public CachingExecutor(Executor delegate) {
    this.delegate = delegate;
    delegate.setExecutorWrapper(this);
  }
  @Override
  public int update(MappedStatement ms, Object parameterObject) throws SQLException {
      //转发请求给组件对象,可以在转发前后执行一些附加动作
    flushCacheIfRequired(ms);
    return delegate.update(ms, parameterObject);
  }
  //...
 }

   

当然,这个装饰器模式的使用与标准的有点差异,但是完成的功能性质相同。
Cache

在MyBatis中有一级和二级缓存。在BaseExecutor(SimpleExecutor\BatchExecutor的父类)中,存放着一级缓存,org.apache.ibatis.cache.impl.PerpetualCache 是默认缓存的实现。
这里写图片描述

这里写图片描述

而当我们初始化时,会对PerpetualCache进行包装
查看org.apache.ibatis.mapping.CacheBuilder中源码,我们开启二级缓存后会包装多层,比如加上LruCache来进行缓存的清除等。

  public Cache build() {
    setDefaultImplementations();
    Cache cache = newBaseCacheInstance(implementation, id);
    setCacheProperties(cache);
    // issue #352, do not apply decorators to custom caches
    //加上一些装饰
    if (PerpetualCache.class.equals(cache.getClass())) {
      for (Class<? extends Cache> decorator : decorators) {
        cache = newCacheDecoratorInstance(decorator, cache);
        setCacheProperties(cache);
      }
      cache = setStandardDecorators(cache);
    } else if (!LoggingCache.class.isAssignableFrom(cache.getClass())) {
      cache = new LoggingCache(cache);
    }
    return cache;
  }

 

这里写图片描述 MyBastis中的装饰器实现对象
包装完成之后呢,在查询等方法进行缓存操作的时候,就拥有了更强大的功能了。
具体使用

好了,说了这么多,我们看下它是如何使用装饰器模式的吧
这里写图片描述
Cache 组件对象的接口
PerpetualCache 具体组件,是我们需要装饰的对象
LruCache等 是具体装饰类,被装饰的对象
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值