深入动态代理源码
前言: 早期学习了动态代理在实际开发中的使用场景和使用方法,我们也知道了最经典的mybatis的mapper就是采用动态代理来实现的,那么动态代理的背后是怎样的原理?为什么能实现动态代理?为什么动态代理只可以代理接口,而无法代理普通类?为什么动态代理需要传入类的classLoder和接口?带着这些疑问,我们来开启本期的主题:探究动态代理的内部原理。
本篇博客的目录
一:动态代理的基本使用方法
二:动态代理的内部运行过程
三:几个相关的问题
四:总结
一:动态代理的基本使用方法
1.1:简单例子
首先我们来模拟一个简单的动态代理的过程:某歌手去参加一个晚会,需要唱歌,他在演奏的过程中需要别人来报幕:演奏开始、演奏结束,每个歌手都遵循这样的过程,在歌手进行表演的过程,穿插着主持人的开场白和结语,我们来用代码模拟这个场景:
1.2:代理接口
首先我们来定义一个singer接口表示我们将要代理的接口:
public interface Singer { /** * 表演 * @param soonName */ public void perform(String soonName); }
1.3:接口的具体实现类
public class Jay implements Singer { public void perform(String soonName) { System.out.println("接下来我为大家唱一首"+soonName); } }
1.4:辅助类,用来模拟注册人的前后台词
public class Presenter { public void before(){ System.out.println("请开始你的表演!"); } public void after(){ System.out.println("表演结束,大家鼓掌!"); } }
1.5:具体的代理类
这里用proxy.newProxyInstance来创建一个代理类,传入原始类的类加载器和接口与接口InvocationHandler,同时插入Presenter类的before与after方法,用于前置和后置处理
public class SingerProxy { private Presenter presenter; public SingerProxy(Presenter presenter){ this.presenter = presenter; } /** * 获取代理对象 * @return */ public Singer getProxy(){ final Singer jay = new Jay(); Singer singerProxy = (Singer)Proxy.newProxyInstance(jay.getClass().getClassLoader(), jay.getClass().getInterfaces(), new InvocationHandler() {」 public Object invoke(Object proxy, Method me