文章目录
一、接口没有实现类能执行方法吗?
答案:能!
我们看一下这段代码
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//6、执行SQL语句
List<User> users = mapper.selectAllUser(new Random().nextInt());
我们都知道在Mybatis中调用SqlSession的GetMapper方法就可以拿到我们的Mapper,然后调用Mapper中的方法就能去查询数据库得到数据。
我们可以看到我们的Mapper并没有实现类啊,为什么能执行方法体呢?
二、动态代理
可想而知是我们的Mybatis通过动态代理技术帮我们生成的代理类去执行我们的方法
三、源码分析
1. GetMapper()方法
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//初始化代理工厂
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {z
// 返回我们生成的代理类
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
2.newInstance()方法
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
//生成代理类并返回,
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
四、问题思考
1、Mybatis中一个接口如果有多个方法的话会走同一个代理类吗?
newInstance(SqlSession sqlSession)
通过源码我们可以看出来 这个跟sqlSession有关系
1.如果用getMapper取同一个Mapper同一个Mapper执行不同方法会走同一个invok方法
2.不同Mapper走不同的invok方法
Mybatis基于多个不同的接口声带代理类,不同的接口肯定不同的invok,相同的接口,不同方法肯定会执行统一哥invoke方法