文章插图
这篇文章解决三个问题:
1.What 动态代理是什么
2.How 动态代理怎么用
3.Why 动态代理的原理
动态代理是什么?
动态代理是代理模式的一种具体实现,是指在程序运行期间,动态的生成目标对象的代理类(直接加载在内存中的字节码文件),实现对目标对象所有方法的增强 。通过这种方式,我们可以在不改变(或无法改变)目标对象源码的情况下,对目标对象的方法执行前后进行干预 。
动态代理怎么用?
首先,准备好我们需要代理的类和接口,因为JDK的动态代理是基于接口实现的,所以被代理的对象必须要有接口 。
/*** SaySomething接口*/public interface SaySomething {public void sayHello();public void sayBye();}
/*** SaySomething的实现类*/public class SaySomethingImpl implements SaySomething {@Overridepublic void sayHello() {System.out.println("Hello World");}@Overridepublic void sayBye() {System.out.println("Bye Bye");}}
按照动态代理的用法,需要自定义一个处理器,用来编写自定义逻辑,实现对被代理对象的增强 。
自定义的处理器需要满足以下要求:
- 需要实现InvocationHandler,重写invoke方法,在invoke方法中通过加入自定义逻辑,实现对目标对象的增强 。
- 需要持有一个成员变量,成员变量的是被代理对象的实例,通过构造参数传入 。(用来支持反射调用被代理对象的方法)
- 需要提供一个参数为被代理对象接口类的有参构造 。(用来支持反射调用被代理对象的方法)
/*** 自定义的处理器,用来编写自定义逻辑,实现对被代理对象的增强*/public class CustomHandler implements InvocationHandler {//需要有一个成员变量,成员变量为被代理对象,通过构造参数传入,用来支持方法的反射调用 。private SaySomething obj;//需要有一个有参构造,通过构造函数将被代理对象的实例传入,用来支持方法的反射调用public CustomHandler(SaySomething obj) {this.obj = obj;}/*** proxy:动态生成的代理类对象com.sun.proxy.$Proxy0* method:被代理对象的真实的方法的Method对象* args:调用方法时的入参*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//目标方法执行前的自定义逻辑处理System.out.println("-----before------");//执行目标对象的方法,使用反射来执行方法,反射需要传入目标对象,此时用到了成员变量obj 。Object result = method.invoke(obj, args);//目标方法执行后的自定义逻辑处理System.out.println("-----after------");return result;}}
这样我们就完成了自定义处理器的编写,同时在invoke方法中实现对了代理对象方法的增强,被代理类的所有方法的执行都会执行我们自定义的逻辑 。
接下来,需要通过Proxy,newProxyInstance()方法来生成代理对象的实例,并进行方法调用测试 。
public class JdkProxyTest {public static void main(String[] args) {//将生成的代理对象的字节码文件 保存到硬盘System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//被代理对象的实例SaySomething obj = new SaySomethingImpl();//通过构造函数,传入被代理对象的实例,生成处理器的实例InvocationHandler handler = new CustomHandler(obj);//通过Proxy.newProxyInstance方法,传入被代理对象Class对象、处理器实例,生成代理对象实例SaySomething proxyInstance = (SaySomething) Proxy.newProxyInstance(obj.getClass().getClassLoader(),new Class[]{SaySomething.class}, handler);//调用生成的代理对象的sayHello方法proxyInstance.sayHello();System.out.println("===================分割线==================");//调用生成的代理对象的sayBye方法proxyInstance.sayBye();}}
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:
- Linux和Unix的那些事儿 UNIX和Linux
- 2 白酒起源探讨:李白一顿能喝4斤,他们唐朝人喝的到底是啥酒
- 丝瓜最好吃的简单做法 丝瓜怎么好吃又简单的做法
- 刷牙究竟能不能省心?100天一充的T9U电动牙刷使用体验
- 电动牙刷的正确使用方法 电动牙刷的正确使用方法图片
- 判断一条鱼的年龄 怎么判断一条鱼的年龄
- 多数情况下通过什么判断鱼的年龄 多数情况下通过什么来判断鱼的年龄
- 你知道怎么识别鱼的年龄吗 如何识别鱼的年龄
- 红玛瑙的魅力 什么样的红玛瑙
- 用鲑鱼精子制造的塑料替代品来了,可以被水回收