静态代理模式
- 代理模式(proxy)指的是为一个对象提供一个代理以控制外界对该对象的访问,比如有些情况下对象A不能直接访问对象B,此时可以为对象B创建一个代理C,然后对象A通过访问代理C来间接访问对象B。
- 有的时候我们希望增强某个方法的功能,但是有不方便直接修改该方法,此时也可通过代理来实现,即在该方法执行的前后做一些事情。
- 静态代理是指代理类和相关的方法直接在代码中写死。
Mybatis中使用静态代理的接口Executor
这里的代理类为 CachingExecutor,被代理类(目标类)为SimpleExecutor、ReuseExecutor或BatchExecutor
- 代理类和被代理类实现相同的接口
- 代理类维护被代理类的一个实例
- 代理类实际上是调用被代理的方法,只是在方法调用前后添加一些功能
- 代理类不会对目标类的代码进行修改
接口
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
int update(MappedStatement ms, Object parameter) throws SQLException;
}
复制代码
被代理类
public abstract class BaseExecutor implements Executor {
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
if (closed) {
throw new ExecutorException("Executor was closed.");
}
clearLocalCache();
return doUpdate(ms, parameter);
}
}
复制代码
代理类
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);
}
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
// 通过代理,加入缓存相关的逻辑。即启用缓存:有缓存直接返回,无缓存查数据库并加到缓存,不启用缓存:直接调用代理类的方法
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, parameterObject, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
}
复制代码