Mybatis可以通过@Dao的注解直接把接口的实现对象给取出,大家都知道,接口是不可实例化的,也就是不能创建对象,但是我们只声明了接口,那么这个实例是怎么来的呢?MyBatis使用了动态代理,真正的对象是增强过的InvocationHandlerpackage java.lang.reflect.Proxy源码:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
通过getAnnotation方法取出目标注解Dao,在InvocationHandler接口的实现中,对标明了@Dao的Mapper方法进行增强
---测试Mapper类如下:package zxj.proxy;public interface Animal {@Dao("走")public void run();@Dao("吃")public void eat();@Dao("叫")public String call();}---代理实现如下:InvocationHandler handler = new InvocationHandler() {/*** 代理对象 执行方法 方法参数*/@Overridepublic Object invoke(Object handler, Method method, Object[] params) throws Throwable {Dao dao = method.getAnnotation(Dao.class);if (null != dao) {String value = dao.value();System.out.println(value);} else {System.out.println("null");}Class<?> returnType = method.getReturnType();System.out.println(returnType.getName());return null;}};@SuppressWarnings("unchecked")Class<Animal> cl = (Class<Animal>) Class.forName("zxj.proxy.Animal");Class<?>[] cc = { cl };Object instance = Proxy.newProxyInstance(Animal.class.getClassLoader(), cc, handler);System.out.println(instance.getClass().getName());Animal an = (Animal) instance;an.run();an.call();an.eat();
