Java动态代理

Java动态代理

代理模式主要是指为类提供一个代理对象来间接地访问该类对象,并且可以在代理对象中完成一些通用的操作,例如为代理对象的每个函数都计算执行时间,为了降低代码冗余性,我们通过代理模式,间接的执行类中的方法,并在执行前后计算运行时间。代理并不实现被代理的方法,只是调用被代理类的方法

静态代理

静态代理主要是指创建代理类并实现接口中的方法,并在代理类中调用被代理类的实际方法。

被代理类

public class Worker implements Person{
    @Override
    public String work() {
        System.out.println("worker...");
        return "worker";
    }
}

接口

public interface Person {
    String work();
}

代理类

public class WorkerProxy implements Person{
    private Worker worker;
    @Override
       public String work() {
        long startTime = System.currentTimeMillis();
        worker.work();//调用worker的实际方法
        long endTime = System.currentTimeMillis();
        System.out.println("程序用时:" + (endTime - startTime));
    }
}

调用代理类

public static void main(String[] args) {
    WorkerProxy workerProxy = new workerProxy();
    workerProxy.work();
}

动态代理

Java中静态代理是指通过代码静态地为每个类都编写一个代理类,当我们需要为很多类中的方法进行如上操作时,就会显得十分繁琐,且我们使用一些闭源、无法修改的的代码时,无法为其编写静态代理方法。此时我们通过反射机制,在程序运行时动态地创建代理类。

动态代理的实现

  • 实现InvocationHandler接口并实现invoke方法,调用类的方法都会转入invoke方法中执行

    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
    

    proxy:代理对象

    method:执行的方法

    args:执行时的参数

  • 为代理类指定ClassLoaderinterface创建代理类

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
    

    loader:类加载器

    interface:interface对象数组,表示给代理对象提供的接口,也就是说声明了代理类的接口,代理类才可以调用方法

    h:invocationHandler:表示动态代理对象调用方法会关联到哪个InvocationHandler对象上(调用invoke)

  • 通过反射获得被代理类构造函数

  • 获得代理类的实例并调用方法

eg:

Person接口与Worker类不发生变化

代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class WorkHandler implements InvocationHandler {
    private Object obj;

    public WorkHandler() {
    }

    public WorkHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.nanoTime();
        //指定被代理对象的方法
        Object invoke=method.invoke(obj,args);
        long endTime = System.nanoTime();
        System.out.println("程序用时:" + ( (endTime - startTime) / 1000L));
        return invoke;
    }
}

执行动态代理

public class Consumer {
    public static void main(String[] args) {
        Person p=new Worker();
        //创建invocationHandler对象
        InvocationHandler invocationHandler=new WorkHandler(p);
        Person proxy=(Person) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(), p.getClass().getInterfaces(),invocationHandler);
        System.out.println(proxy.work());
    }
}

代码地址

posted @ 2021-10-29 18:08  流光之中  阅读(66)  评论(0)    收藏  举报