上一章说了,既然mybatis获取Mapper的时候使用的是代理,那么我们是否可以模拟实现一下。
话不多说上代码;
这样就更加清楚mapper的代理实现过程了吧。
public class MySqlSession {
public static Object getMapper(Class clazz){
ClassLoader classLoader = MySqlSession.class.getClassLoader();
Class[] classes = {clazz};
Object proxy = Proxy.newProxyInstance(classLoader, classes, new MyTestInvocationHandler());
return proxy;
}
static class MyTestInvocationHandler implements InvocationHandler{
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//这个是判断要执行的方法是在Object声明的方法,
// 比如toString这种,就不需要我们通过代理实现
if(method.getDeclaringClass().equals(Object.class)){
method.invoke(this, args);
}
Select select = method.getAnnotation(Select.class);
//取出@select注解中的sql语句。数组是因为注解中可以写多条sql语句
String sql = select.value()[0];
System.out.println("假装连接数据库");
System.out.println("假装执行了查询语句"+sql);
System.out.println("假装返回了JSON串");
return null;
}
}
}
@Test
public void customBatis(){
TMapper tMapper = (TMapper)MySqlSession.getMapper(TMapper.class);
tMapper.queryMap("1");
}
//打印结果
假装连接数据库
假装执行了查询语句select * from t where id = ${id}
假装返回了JSON串
有些同学会发散思维了,说既然这个我们可以实现,那是不是我们可以自己开发一个mybatis框架来让市面上的人使用呢。
可以,但是要解决一些问题,比如这个:
我们都知道在service中调用mapper的时候,是通过Autowired来进行注入的,但是你这个mapper是在使用的时候才通过代理对象生成,那么spring在初始化的时候找不到这个mapper,注入不了必定是要报错的。
问题就是:如何将一个第三方的对象注入到Spring呢?