动态代理

有一段时间没有写文章了, 主要是回想起这两年多的时间,多多少少,每个知识点差不多都有写到了, 一时也想不起什么新鲜的知识分享给大家.今天写动态代理,主要是在看Mybatis源码时,发现真的是把动态代理用的是太6 了, 感叹之余,有一些心得,和大家分享一下.

我所理解的动态代理

其实网上对动态代理的解释有很多了,我就不赘述那些概念了, 于小刀看来, 目的只有一个,那就是可以自定义逻辑,可以添加逻辑. 在本文中,我想写的是可以自定义逻辑, 在此之前,我们先看一下通常的动态代理的代码

动态代理代码

源码地址:

https://github.com/xiaodaojava/sunshine/tree/master/sunshine-base/src/main/java/red/lixiang/tools/demo/proxy/dynamic

接口

 

实现类

 

代理类

 

Main函数

 

我们在运行的时候打个断点,可以看到:

 

如上图所示,我们虽然把jdk生成的代理对象强转成了Greet,但实际上是Proxy类型,运行结果如下图所示:

 

进入正文

上面这些代码, 是平常的增加逻辑的用法,但,今天小刀想和大家聊的是: 自定义逻辑.先看代码 接口不变,

代理类

 

main函数

 

运行结果如下:

 

全文的重点

是可以正常运行的, 这里会打破大家一个思维定式,就是代理类里面并不一定需要真正的处理对象, 可能全部都是自定义的逻辑.

源码中的应用

主要是mybatis , 我们想一下, 在写sql时, 我们经常DAO里面都是接口和定义的方法, 然后mapper的xml里面写SQL, 那么这两者是怎么对应起来的呢? 今天先不细讲, 只是看看动态代理的使用,要出场的是MapperProxyMapperProxyFactory:

 

我们可以看到,传入的InvocationHandler实际上是mapperProxy

 

cachedInvoker 通过源码,我们可以跟踪到的代码:

 

最终我们可以看到:

 

然后使用sqlSession去执行Sql

总结

如上mybatis中对动态代理的使用,并没有实现类,正是在invoke方法中,直接调用了sqlSession去执行SQL , 刚开始看到这块时, 不是很好理解 , 要破开思维, 为什么动态代理一定要有代理对象呢? 我们也完全可以自己模拟逻辑!