MyBatis源码中装饰器模式

MyBatis中关于Cache和CachingExecutor接口的实现类也使用了装饰者设计模式。Executor是MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护;CachingExecutor是一个Executor的装饰器,给一个Executor增加了缓存的功能。此时可以看做是对Executor类的一个增强,故使用装饰器模式是合适的。

2.1.1 Executor

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

  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
  2. executorType = executorType == null ? defaultExecutorType : executorType;
  3. executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  4. Executor executor;
  5. if (ExecutorType.BATCH == executorType) {
  6. executor = new BatchExecutor(this, transaction);
  7. } else if (ExecutorType.REUSE == executorType) {
  8. executor = new ReuseExecutor(this, transaction);
  9. } else {
  10. executor = new SimpleExecutor(this, transaction);
  11. }
  12. //如果开启了二级缓存则装饰原先的Executor
  13. if (cacheEnabled) {
  14. executor = new CachingExecutor(executor);
  15. }
  16. executor = (Executor) interceptorChain.pluginAll(executor);
  17. return executor;
  18. }

image.png

2.1.2 CachingExecutor (装饰器的具体实现对象)

  1. public class CachingExecutor implements Executor {
  2. //持有组件对象
  3. private Executor delegate;
  4. private TransactionalCacheManager tcm = new TransactionalCacheManager();
  5. //构造方法,传入组件对象
  6. public CachingExecutor(Executor delegate) {
  7. this.delegate = delegate;
  8. delegate.setExecutorWrapper(this);
  9. }
  10. @Override
  11. public int update(MappedStatement ms, Object parameterObject) throws SQLException {
  12. //转发请求给组件对象,可以在转发前后执行一些附加动作
  13. flushCacheIfRequired(ms);
  14. return delegate.update(ms, parameterObject);
  15. }
  16. //...
  17. }