还是直接看代码实现吧
首先定义一个实体
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接口
public interface UserMapper { User getUserById(Integer id);}
然后自定义一个invacationHandle
public class MapperProxy implements InvocationHandler { /** * 利用Proxy.newProxyInstance 获取代理类 * @param clz 目标接口 * @param* @return */ @SuppressWarnings("unchecked") public T newInstance(Class 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());}
输出结果
mybatis底层源码就是这么实现的,看看mybatis是怎么写的吧
@Overridepublic 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