美文网首页
MyBatis插件实现日记

MyBatis插件实现日记

作者: _palm | 来源:发表于2018-01-09 20:56 被阅读13次

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<T> {
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap();

    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    public Class<T> getMapperInterface() {
        return this.mapperInterface;
    }

    public Map<Method, MapperMethod> getMethodCache() {
        return this.methodCache;
    }

    protected T newInstance(MapperProxy<T> 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> T getMapper(Class<T> type) {
    return this.configuration.getMapper(type, this);
}

//Configuration
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return this.mapperRegistry.getMapper(type, sqlSession);
}
//MapperRegistry
public <T> T getMapper(Class<T> 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);
        }
    }
}

相关文章

网友评论

      本文标题:MyBatis插件实现日记

      本文链接:https://www.haomeiwen.com/subject/tlggnxtx.html