实现动态代理的步骤:
1、创建接口,定义目标类要完成的功能(也就是目标接口,你要通过代理执行的目标类)
2、创建目标类实现接口(接口的实现类)
动态代理中,我们最终要获得的是我们需要的代理类,通过Proxy类的newProxyInstance方法来实例化我们需要的类
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
其中三个参数
第一个:ClassLoader loader类加载器,是我们目标接口(target)实现类的类加载器
通过 target.getClass().getClassLoader() 获取
第二个:Class<?>[] interfaces为我们的目标接口
通过target.getClass().getInterfaces() 获取
第三个:是一个InvocationHandler 类型的对象,这只是一个接口,我们需要实现这个接口,实现类中实现的方法就是接下来的invoke方法
Proxy类并不会完全代理所有的东西,相当于一个传话人,我们需要将我们所要调用的目标方法和所需要增加的新的功能传进去,Proxy类来将我们所调用的接口中方法传入invoke函数中,再将结果进行返回,Proxy充当中间人,只是给了invoke所需的方法,将整个过程进行组合
3、创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
- 调用目标方法
- 增强功能
4、使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。
具体的流程如下:
创建接口,定义目标类要完成的功能
以售卖Usb为例
此处创建目标接口,接口中为sell方法,参数为我们传入的数量
//目标接口
public interface UsbServer {
float sell(int amount);
}
创建目标类实现接口
对刚才创建的接口,创建一个实现类
//目标类
public class UsbServerImpl implements UsbServer{
@Override //目标方法
public float sell(int amount) {
System.out.println("目标类中,执行sell目标方法");
return 85.0f*amount;
}
}
上面的接口与实现类,在一般的业务中都需要定义
接下来的才是动态代理需要做的事情
创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
实现InvocationHandler接口,实现invoke方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//必须实现InvocationHandler接口,完成代理类要做的功能(1、调用目标方法 2、功能增强)
public class MySellHandler implements InvocationHandler {
private Object target = null;
//动态代理:目标是活动的,不是固定的,需要传入进来
//传入是谁,就给谁创建代理
public MySellHandler(Object target) {
//给目标对象赋值
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(target, args); // 执行目标方法
//增强功能,增加Usb价格
if(res != null){
Float price = (Float) res;
price = price +25;
res = price;
}
return res;
}
}
使用Proxy类的静态方法,创建代理对象
//创建代理对象,使用Proxy
//1.创建目标对象
UsbServer usbServer = new UsbServerImpl();
//2.创建InvocationHandler对象
MySellHandler sellHandler = new MySellHandler(usbServer);
//3.创建代理对象
UsbServer proxy = (UsbServer) Proxy.newProxyInstance(usbServer.getClass().getClassLoader(),
usbServer.getClass().getInterfaces(), sellHandler);
//4.通过代理执行方法
float price = proxy.sell(1);
System.out.println("通过动态代理对象,调用方法"+price);