一文搞懂代理模式
1. 代理模式的功能与作用
代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。
**静态代理模式:**在程序运行前就已经创建好代理类,当需要代理多个类时,不易维护和修改。
**动态代理模式:**在程序运行时根据需求创建代理类并生成一个代理对象,来代理真实对象,从能够通过代理对象来完成需要实现的操作。
1.1 代理模式的好处
好处:代理模式中代理对象是可以在目标对象实现的基础上,增强额外的功能操作,也是方法的增强。
思想:在编程中不能随意修改已经写好的代码,如果需要修改可以通过代理的方式来扩展该方法。
2. 动态代理代码解析及封装
2.1 定义一个接口
package demo1;
public interface A {
int test(int num);
}
2.2 定义一个接口的实现类
package demo1;
public class TypeA implements A{
@Override
public int test(int num) {
return num + 10;
}
}
2.3 定义一个代理类
import java.lang.reflect.Proxy;
public class ProxyTest {
//这是一个获取代理对象的方法,参数是需要被代理类实现的接口对象,返回值是一个代理类对象
public static <T> T getProxyInstance(Class<T> tClass){
/*通过JDK提供的原生类Proxy中的newProxyInstance方法获取一个代理类对象
参数:1. 被代理类的类加载器
2.被代理类所实现的接口
3. 实现了InvocationHandler接口的类的对象
*/
return (T) Proxy.newProxyInstance(
tClass.getClassLoader(),
new Class[]{tClass},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("test".equals(method.getName())){
int a = (int) args[0];
return a*10 +10;
}
return null;
}
}
);
}
}
2.4 测试
package demo1;
public class Demo1 {
public static void main(String[] args) {
//调用getProxyInstance方法,得到一个代理对象,参数是A接口.class对象
A proxyInstance = ProxyTest.getProxyInstance(A.class);
//代理对象调用test方法会进入invoke方法中执行
int test = proxyInstance.test(5);
System.out.println(test);
//未代理结果15,代理结果 5*10 + 10.
}
}
第三个参数中重写的invoke方法:代理类调用被代理类的方法时,会直接调用到InvocationHandler中的invoke方法,然后可以通过反射调用真正目标方法,同时可以在目标方法前后加上新增的逻辑,以此实现对方法的增强,实现代理的效果。
重写的invoke方法有三个参数:
proxy: 代理类对象
method:代理类所调用的具体哪个方法,这里是通过反射,通过方法名拿到具体的方法,我们就可以通过invoke方法调用了。
args:当前method方法所包含的参数
但我们知道,反射中的invoke方法需要两个参数,这里解释一下:
参数一:当前方法所属的类的对象,这里就是被代理类的对象,也就是构造方法初始化的object对 象,也就是我们的被代理类。
参数二:方法的参数