仍是直接看代码实现吧sql
首先定义一个实体mybatis
public class User { private Integer id; private String name; private int age; public User(Integer id, String name, int age) { this.id = id; this.name = name; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
在定义一个mapper接口app
public interface UserMapper { User getUserById(Integer id); }
而后自定义一个invacationHandleide
public class MapperProxy implements InvocationHandler { /** * 利用Proxy.newProxyInstance 获取代理类 * @param clz 目标接口 * @param <T> * @return */ @SuppressWarnings("unchecked") public <T> T newInstance(Class<T> clz) { return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] { clz }, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //判断method是不是Object类中定义的方法 //如 hashCode()、toString()、equals() //若是是则将target 指向 this //若是直接调用 method.invoke 会报空指针错误 if (Object.class.equals(method.getDeclaringClass())) { try { return method.invoke(this, args); } catch (Throwable t) { } } // 投鞭断流 // mybatis mapper底层实现原理 return findUserById((Integer) args[0]); } private User findUserById(Integer id) { return new User(id, "zhangsan", 18); } }
测试测试
public static void main(String[] args) { MapperProxy proxy = new MapperProxy(); //获取代理类 UserMapper mapper = proxy.newInstance(UserMapper.class); User user = mapper.getUserById(1001); System.out.println("ID:" + user.getId()); System.out.println("Name:" + user.getName()); System.out.println("Age:" + user.getAge()); System.out.println(mapper.toString()); }
输出结果this
mybatis底层源码就是这么实现的,看看mybatis是怎么写的吧代理
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } else if (isDefaultMethod(method)) { return invokeDefaultMethod(proxy, method, args); } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args); }
是否是很像 除了最后的return指针