为啥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<T>,到当获取Mapper,依据类型或者对应的MapperProxyFactory,应用JDK动静代理API创立代理对象。于是咱们就能够调用法了。
演示相干代码
欢送探讨学习
应用JDK API实现动静代理和源码剖析
Mybatis 插件和动静代理
面试官问,为啥Mybatis的接口不须要实现类
面试官问,Mybatis插件加强逻辑的程序怎么管制