爲啥Mybatis的接口不需要實現類
對啊,爲什麼不需要啊?
猜猜,可能是動態代理生成了接口的對應的類
果然是動態生成的
那是啥時候生成的呢
那就是我通過class
獲取Mapper
時生成的
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
通過上面我們一層層進入到下面的代碼
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);// 1
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance(sqlSession); // 2
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
- 獲取對應類型的MapperProxyFactory
- 創建MapperProxy,也就是我們的UserMapper,我們就可以在其上調用我們在接口中定義的方法了
具體是怎麼生成代理的呢?
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy); // 1
}
- 進入newInstance方法如下
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
在這裏我們又到了Proxy.newProxyInstance
代碼,就是JDK創建代理的方法。
稍等,生成Proxy的MapperProxyFactory從而來
彆着急我還沒有說完呢
knownMappers.get(type)
剛纔我們通過這個獲取的MapperProxyFactory<T>
,其中包含生成代理的接口集合mapperInterface
現在我說說,MapperProxyFactory
從何而來,簡單說就是在解析XML時創建的
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
我們一直進入到parseConfiguration方法,其中mapperElement(root.evalNode("mappers"));
方法就是解析Mapper文件,註冊的MapperProxyFactory
到MapperRegistry
。一直跟蹤到下面的方法,在MapperRegistry
中。
public <T> void addMapper(Class<T> type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
knownMappers.put(type, new MapperProxyFactory<>(type)); // 1
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
- 一直追蹤到
knownMappers.put(type, new MapperProxyFactory<>(type));
方法我們找到了,在創建代理的時候,是用的是get
方法,MapperProxyFactory
就是從這添加的。
總結
今天我們從爲Mapper接口創建代理對象開發,說到具體怎麼創建對象。
從初始化配置文件,創建MapperProxyFactory,到當獲取Mapper,根據類型或者對應的MapperProxyFactory,使用JDK動態代理API創建代理對象。於是我們就可以調用法了。
歡迎討論學習