关于JDK动态代理

在学习Spring的AOP部分时,发现我对代理模式尤其是动态代理的了解太少,为了更加透彻的理解写的笔记,如果有写错的地方或者有更好的理解方式欢迎指正

在理解JDK动态代理之前需要先理解一下Java反射

JDK动态代理

我们用一个例子(房屋出租)来理解动态代理:

//被代理类
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("租房!");
    }
}
//接口
public interface Rent {
    public void rent();
}

JDK动态代理主要涉及两个类:java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler

  • Proxy类为代理类,提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类
  • InvocationHandler调用逻辑处理器类,这个接口实现的类中维护一个目标对象,这个对象是被代理的对象

public interface InvocationHandler

  • InvocationHandler是由代理实例的调用处理程序实现的接口 。
  • 每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。

Object invoke(Object proxy,方法 method,Object[] args) throws Throwable

  • 处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。

参数:
proxy - 调用该方法的代理实例
method -所述方法对应于调用代理实例上的接口方法的实例
args -包含的方法调用传递代理实例的参数值的对象的阵列

  • 可以理解为额外要加的部分写到InvocationHandler重写的invoke方法中

写我们例子中的调用逻辑处理器类

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

//这个类生成自动代理类
public class ProxyInvocationhandler implements InvocationHandler {

    private Object rent;

    public void setRent(Object rent){
        this.rent = rent;
    }
    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		//额外加的方法
		cry();
        Object result = method.invoke(rent, args);
        smile();
        return result;
    }
    
    public void cry(){
        System.out.println("Java真难~~~~~~~~");
    }
    
    public void smile(){
        System.out.println("Java真简单~~~~~~~");
    }
}

获取动态生成的代理类的对象须借助 Proxy 类的 newProxyInstance 方法

public class Proxy

Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。

动态代理类是一个实现在类创建时在运行时指定的接口列表的类
每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler

写个测试类:

public static void main(String[] args) {
        //真实角色
        Host host = new Host();
        //代理角色
        ProxyInvocationhandler pih = new ProxyInvocationhandler();

        pih.setRent(host);
        //创建一个代理对象
        Rent proxy = (Rent)pih.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
        System.out.println("调用rent");
        proxy.rent();
    }

控制台输出:

调用rent
Java真难~~~~~~~~
租房!
Java真简单~~~~~~~
上一篇:关于strlen和sizeof的使用


下一篇:牛客网——取中值