美文网首页Java 杂谈
静态代理和动态代理

静态代理和动态代理

作者: 正规程序员 | 来源:发表于2019-01-24 00:01 被阅读0次

代理是一种软件设计模式,目的是通过不直接调用被代理对象而访问其方法,提高代码重用率。

一般用于框架本身处理多种业务逻辑时,通过代理机制方便业务方调用,也利于框架的拓展和解耦。在代码编译时就确定目标类是哪个,可用静态代理。动态代理是在代码运行时加载目标类。

静态代理步骤:

  1. 目标类和代理类都实现相同的业务接口;
  2. 代理类的构造方法中传入目标类的实例;
  3. 在代理类的接口实现中调用目标类实例的接口方法;

静态代理的缺点是不同的业务,需要实现多个目标实现类,代码冗余高。

动态代理原理:
动态代理中涉及到InvocationHandler接口和Proxy类。

Proxy类的newProxyInstance()方法负责代理类实例的创建。

  public static Object newProxyInstance(
      ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
  • ClassLoader loader:指定一个动态加载代理类的类加载器。
  • Class<?>[] interfaces:指明目标类实现的接口。
  • InvocationHandler h:方法委托类。

Proxy类与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。

InvocationHandler的接口方法是invoke(),通过代理类调用目标类方法时,最终都会委托此方法执行。

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable;
}
  • Object proxy:代理类实例
  • Method method:调用的方法对象
  • Object[] args:调用的参数

一般会在此方法前后增加一些操作,对某个业务流程补充完善子流程,即面向切面编程(AOP)。

面向切面编程(AOP):是在一系列纵向的控制流程中,把那些相同的子流程提取成一个横向的面。即通过预编译方式和运行期动态代理,实现在不修改源代码的情况下给程序统一添加功能的技术思想。

动态代理步骤:

  1. 创建目标业务接口和实现类实例;
  2. 通过Proxy类的newProxyInstance()方法获取代理类实例;
  3. 创建InvocationHandler方法委托类实例,实现代理类到目标类的方法分派,并支持在目标类业务前后增改操作;

目标类及其接口 示例如下:

/**
 * 目标业务接口
 */
public interface IProxy {
    void print();
}

/**
 * 目标类——实现目标业务接口
 */
public class MyProxy implements IProxy {
    @Override
    public void print() {
        Log.d("test","面向AOP编程——进行中");
    }
}

方法委托类 示例如下:

/**
 * 方法委托类——实现InvocationHandler接口
 */
public class MyInvocationHandler implements InvocationHandler {
    private MyProxy myProxy;

    /**
     * 通过构造器注入被目标类实例
     * @param myProxy
     */
    public MyInvocationHandler(MyProxy myProxy) {
        this.myProxy = myProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Log.d("test", "面向AOP编程——准备中");//模拟前置操作
        Object object = method.invoke(this.myProxy, args);//通过反射调用目标类方法
        Log.d("test", "面向AOP编程——结束后");//模拟后置操作
        return object;
    }
}

外部框架调用目标类 示例如下:

private void testProxy() {
     MyProxy myProxy = new MyProxy();
     IProxy iProxy = (IProxy) Proxy.newProxyInstance(
             Thread.currentThread().getContextClassLoader(),
             myProxy.getClass().getInterfaces(),
             new MyInvocationHandler(myProxy));
     iProxy.print();
}

ClassLoader是类装载器,将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。 因此每次生成动态代理类对象时都需要指定一个类装载器对象。

打印log如下:

D/test: 面向AOP编程——准备中
D/test: 面向AOP编程——进行中
D/test: 面向AOP编程——结束后

相关文章

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • 静态代理、动态代理

    代理分为静态代理和动态代理 按照代理创建的时期,可以分为静态代理和动态代理: (1) 静态代理:由程序员或者...

  • JAVA动态代理的实现方式

    1. 静态代理VS动态代理 代理类可以增强被代理对象的方法。可分为静态代理和动态代理。 1.1 静态代理 静态代理...

  • Spring之代理模式

    九、代理模式 目录:静态代理、动态代理AOP的底层机制就是动态代理。代理模式分为静态代理和动态代理。接触aop之前...

  • Java 代理的实现原理

    一、怎样使用代理 二、代理实现的原理 一、代理分为静态代理和动态代理 静态代理:代理对象获得目标对象的引用 动态代...

  • 带你初识Java的代理模式

    Spring AOP是基于动态代理设计模式实现的,相对的就有静态代理 动态代理和静态代理 静态代理 对于静态代理,...

  • 设计模式之代理模式

    代理分为静态代理和动态代理。 动态代理又包括基于JDK的动态代理、基于CGlib 的动态代理、基于Aspectj实...

  • Java高级主题(五)——动态代理

    代理可以分为静态代理、动态代理,动态代理又可以分为 jvm的动态代理 和 cglib的动态代理。像spring框架...

  • java静态代理与动态代理简单分析

    原链接地址 1、动态代理(Dynamic Proxy) 代理分为静态代理和动态代理,静态代理是在编译时就将接口、实...

  • 动态代理和静态代理

    一、什么是静态代理和动态代理 静态代理:手动的创建代理类在程序运行前代理类就已经存在了。 动态代理...

网友评论

    本文标题:静态代理和动态代理

    本文链接:https://www.haomeiwen.com/subject/fiyejqtx.html