一篇文章让你搞懂Java中的静态代理和动态代理( 二 )


上述静态代理在程序运行前就需要把对应的类和方法写好 , 这样就被写死了 , 这只是一个简单的接口里面也只有两个方法 , 那如果接口中有几十个方法都需要扩展呢 , 总不能一个个地手动去添加吧 , 所以有了我们的动态代理
实现步骤:

  1. 定义一个接口和接口的实现类
  2. 创建一个代理类实现InvocationHandler接口(指定运行时生成代理类需要完成的具体任务
  3. 重写InvocationHandler接口中的invoke方法
  4. 创建被代理类的对象 , 调用处理程序最后通过代理类对象来调用对应方法
代码实现:
/** * 目标接口 */interface Hobby {void sing();void dance();}/** * 目标类 */class MyHobby implements Hobby {@Overridepublic void sing() {System.out.println("sing...");}@Overridepublic void dance() {System.out.println("dance...");}}/** * 代理类 */class HobbyDynamicProxy implements InvocationHandler{private final Object obj;public HobbyDynamicProxy(Object obj){this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {rap();Object result = method.invoke(obj, args);rap();return result;}public void rap() {System.out.println("Dynamic-rap...");}}/** * main方法 */class Test {public static void main(String[] args) {InvocationHandler renterHandler = new HobbyDynamicProxy(new MyHobby());Hobby hobbyProxy = (Hobby)Proxy.newProxyInstance(Hobby.class.getClassLoader(), new Class[]{Hobby.class},renterHandler);hobbyProxy.sing();hobbyProxy.dance();}}输出结果:
一篇文章让你搞懂Java中的静态代理和动态代理

文章插图

InvocationHandler 接口 和 invoke 方法介绍InvokationHandler是Java 反射包里面的一个接口通过用户类来实现 , 来激发一个动态代理类的方法 。
它只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
  1. Object:实现方法的代理对象
  2. Method:代理实例激发的方法 , Porxy参数中的接口方法
  3. Object[]:传递给方法的一系列参数

静态代理和动态代理的区别静态代理:
在jvm运行之前就已经获取到代理类的class信息 。代理类需要开发者自己写好 , 即开发者需要自己实现代理类的.java文件 , 也就是说在项目编译之前就需要存在代理类的.java文件 , 然后在编译阶段就可以将代理类的.java文件编译成.class文件 , 从而得到代理类的class信息;
动态代理:
不需要开发人员自己实现代理类的 , 也就是项目代码中是不存在代理类的.java文件的 , 既然代理类未由开发者实现 , 那么程序经过编译之后肯定也不会有代理类的.class文件 。也就是说经过编译之后程序未启动运行之前 , 关于代理类的信息我们一无所知 , 它是在程序运行过程中需要用到的时候才会由jvm动态生成的 , 而且生成之后也只存在于内存中 , 不会写到磁盘保存成.class文件 , 更加不会保存为.java文件;
总之一句话就是静态代理是需要开发人员自己实现代理类的逻辑的 , 且代理类的class信息是在程序运行之前就已经可以获取到的了 , 而动态代理是不需要开发人员自己实现代理类的 , 
【一篇文章让你搞懂Java中的静态代理和动态代理】

经验总结扩展阅读