代理模式
JDK动态代理
newProxyInstance()的参数含义
// 创建目标对象
OrderService target = new OrderServiceImpl();
// 创建代理对象
// Object proxyObj = Proxy.newProxyInstance(target.getClass.getClassLoader(),
// target.getClass().getInterfaces(),
// 调用处理器)
Object proxyObj = Proxy.newProxyInstance(类加载器,代理类要实现的接口,调用处理器)
/*
1. newProxyInstance 翻译为:新建代理对象
也就是说,调用这个方法可以创建代理对象
本质上,这个Proxy.newProxyInstance()方法的执行,做了两件事
第一件事:在内存中动态的生成了一个代理类的字节码class
第二件事:new对象了。通过内存中生成的代理类这个代码,实例化了代理对象
2. 关于newProxyInstance()方法的三个重要的参数,每一个是什么含义,有什么用?
第一个参数:ClassLoader loader
类加载器。这个类加载器有什么用呢?
在内存当中生成的字节码也是class文件,要执行也得先加载到内存当中,
加载类就需要类加载器,所以这里需要指定类加载器。
并且JDK要求,目标类的类加载器必须和代理类的类加载器使用同一个
第二个参数:Class<?>[] interfaces
代理类和目标类要实现同一个接口或同一些接口
在内存中生成代理类的时候,这个代理类是需要你告诉它实现哪些接口的
第三个参数:InvocationHandler h
InvocationHandler 被翻译为:调用处理器。是一个接口
在调用处理器接口中编写的就是:增强代码。
因为具体要增强什么代码,JDK动态代理技术它是猜不到的
既然是接口,就要写接口的实现类
*/
// 调用代理对象的代理方法
invoke
public Object invoke(Object proxy, Method method, Object[] args){}
-
invoke方法什么时候被调用?
当代理对象调用代理方法的时候,注册在InvocationHandler调用处理器
当中的invoke()方法被调用
-
invoke方法的三个参数:
invoke方法是JDK负责调用的,
所以JDK调用这个方法的时候会自动给我们传过来这三个参数
我们可以在invoke方法的大括号中直接使用
- Object proxy 代理对象的引用,这个参数使用较少
- Method method 目标对象上的目标方法。(要执行的目标方法就是它)
- Object[] args 目标方法上的实参
invoke方法执行过程中,使用method方法来调用目标对象的目标方法
封装动态代理工具类
public class ProxyUtil{
public static Object newProxyInstance(Object target){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new TimerInvocationHandler());
// TimerInvocationHandler 为增强类
}
}