动态代理
-
动态代理和静态代理角色一样的。
-
动态代理类是动态生成的,不是我们直接写好的
-
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
基于接口的——JDK动态代理
基于类的——cglib
Java字节码实现
需要了解两个类:proxy(代理),InvocationHandler(调用处理程序)
InvocationHandler:每个代理势力都有一个关联调用处理程序,当在代理实例上调用方法时,方法调用将被编码并分配到其调用处理程序的Invoke方法。
invoke()方法:需要三个参数。proxy:该方法的代理实例。method:所述方法对应于调用代理实例上的接口方法实例,方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。args:包含的方法调用传递代理实例的参数值的对象阵列,或null如果接口方法设有参数,原始类型的参数包含在适当的原始包装器类的实例中。
废话不多说,下面直接上代码演示。
还是以客户通过中介去租房的抽象实例来演示。
创建一个租房的接口
/**
* @author liang.peng
* @version 1.0
* @description 租房接口
* @since 2022/7/19 9:48
**/
public interface Rent {
public void rent();
}
创建一个房东并实现租房的接口
/**
* @author liang.peng
* @version 1.0
* @description 房东
* @since 2022/7/19 9:54
**/
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房東的房子!");
}
}
创建一个动态代理的类,主要用于在使用的时候去生成代理对象(也就是该实例中的中介)
package com.trs.mybatisplus.controller.demo02;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author liang.peng
* @version 1.0
* @description 使用这个类自动生成代理。
* @since 2022/7/19 13:36
**/
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成都得到的代理类///传入对应的三个参数
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//重写InvocationHandler的方法
@Override//处理代理实例并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质就是使用反射机制实现!
Object result = method.invoke(rent, args);//传入需要代理的rent对像。
return result;
}
}
创建一个客户端去实现一下
/**
* @author liang.peng
* @version 1.0
* @description 客户通过代理去实现租房
* @since 2022/7/19 14:09
**/
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
//通过proxyInvocationHandler来生成一个代理角色
//通过调用程序处理角色来处理我们需要调用接口的对象
proxyInvocationHandler.setRent(host);
//生成一个代理
Rent proxy = (Rent) proxyInvocationHandler.getProxy();
//利用代理来租房
proxy.rent();
}
}
动态代理和静态代理的区别,动态代理的代理对象是在需要的时候可以传入需要代理的对象后自动生成的,而静态代理则是一对一的固定写好的。