MyBatis提供了一个 interceptor
public interface Interceptor {
Object intercept(Invocation var1) throws Throwable;
Object plugin(Object var1); //注册插件
void setProperties(Properties var1);
}
插件需要使用 Intercepts 注解, Signature 描述拦截的方法签名, 如:
@Intercepts({@Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
), @Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
)})
这里拦截 Executor的查询方法[四个参数和六个参数].
MyBatis Mapper接口使用jdk动态代理 具体类为 MapperProxyFactory:
public class MapperProxyFactory {
private final Class mapperInterface;
private final Map methodCache = new ConcurrentHashMap();
public MapperProxyFactory(Class mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class getMapperInterface() {
return this.mapperInterface;
}
public Map getMethodCache() {
return this.methodCache;
}
protected T newInstance(MapperProxy mapperProxy) {
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
MapperProxy mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
return this.newInstance(mapperProxy);
}
}
通过 MapperProxyFactory可以获取具体的Mapper然后调用接口方法.执行数据库操作
流程为:
SqlSessionFactory得到 SqlSession 然后获得 Configuration 然后 获取Mapper :
public T getMapper(Class type) {
return this.configuration.getMapper(type, this);
}
//Configuration
public T getMapper(Class type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}
//MapperRegistry
public T getMapper(Class type, SqlSession sqlSession) {
MapperProxyFactory mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if(mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}