这篇文章主要介绍了JDK动态代理,代理接口没有实现类,实现动态代理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
JDK代理,代理的是接口,那么笔者想一想,既然代理的是接口,那如果没有实现类怎么办,能不能代理。答案是可以的,Mybatis就是这样的。
Mybatis使用JDK动态代理来实现Mapper接口,事先保存好Mapper接口,和接口声明的方法,返回值,参数类型,然后代理类的方法调用的时候使用MapperMethod这个事先放入方法缓存里的对象来真实调用功能。
笔者极度简化了一下代码:
被代理的接口:
public interface Subject2 { String selectById(); }
这个接口可以看成是Mapper接口
代理对象:
public class SubjectProxy2<T> implements InvocationHandler { private Class<T> proxyInterface; //这里可以维护一个缓存,存这个接口的方法抽象的对象 SubjectProxy2(Class<T> proxyInterface){ this.proxyInterface = proxyInterface; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("selectById")){ //String result = (String) method.invoke(proxyInterface,args); //这里可以得到方法抽象对象来调用真的的查询方法 System.out.println("selectById调用成功"); } return null; } public T getProxy(){ return (T) Proxy.newProxyInstance(proxyInterface.getClassLoader(),new Class[]{proxyInterface},this); } }
这个代理类使用了泛型,说明这个代理类可以代理所有的mapper接口。
那么接下来测试一下:
public class ProxyTest2 { public static void main(String[] args) { SubjectProxy2<Subject2> subjectProxy2 = new SubjectProxy2(Subject2.class); Subject2 subject2 = subjectProxy2.getProxy(); subject2.selectById(); } }
结果不言而喻。肯定会有相应的输出
没有看mybatis源码的时候,我以为动态代理一定要要有实现类才能代理,但是看了优秀的顶级大牛的源码之后,我才发现,原来还可以这样。
发表评论 取消回复