JavaWeb Proxy
2019-01-04 本文已影响0人
dawsonenjoy
代理模式
为其他对象提供一种代理来控制对这个对象的访问,比如当一个对象不适合或者不能直接引用另一个对象时,可以通过代理来在客户端和目标对象间起中介的作用
静态代理
结构
一个真正访问的目标类对象,一个代理类对象,两个对象都实现同一个接口,先访问代理对象,再访问真正要访问的对象
示例
1.被两个对象类继承的接口
public interface Proxyed {
//被代理的接口
public void test();
}
2.目标对象类
public class ObjectTest implements Proxyed{
//目标对象继承Proxyed接口
public void test() {
System.out.println("目标对象执行的方法");
}
}
3.代理对象类
public class ProxyTest implements Proxyed {
//代理对象继承Proxyed接口
private Proxyed py;
public ProxyTest(Proxyed py) {
this.py = py; //通过代理访问真正的对象
}
public void test() {
py.test(); //调用真正对象的方法
}
}
4.执行方法
public static void main(String[] args) {
ObjectTest ot = new ObjectTest(); //目标对象
ProxyTest pt = new ProxyTest(ot); //代理对象,传入目标对象
pt.test(); //代理对象访问目标对象方法
}
动态代理
相比静态代理可以直接给目标类对象通过反射机制生成一个代理对象,而无需代理类的存在
动态代理的生成
在java.lang.reflect下提供了Proxy类可以直接给实现接口类的对象直接生成代理对象
常用方法
(1)isProxyClass():当且仅当指定的类通过getProxyClass()或newProxyInstance()方法动态生成为代理类时返回true
(2)getProxyClass():返回代理类的Class对象,并向其提供类加载器和接口数组
(3)getInvocationHandler(proxy):返回指定代理实例的调用处理程序
(4)newProxyInstance():产生一个指定接口的代理类实例,仅能代理实现至少一个接口的类,需传入三个参数:classLoader(类加载器,通过getClassLoader()获取)、interface(代理类要实现的接口,通过getInterfaces()获取)、InvocationHandler(策略设计模式的应用)
注:
InvocationHandler接口需要实现invoke()方法,当有任何调用代理类的方法时,该方法都会执行,有下面三个参数:
(1)proxy:代理本身的引用
(2)method:当前调用的方法
(3)args:当前调用方法用到的参数
示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
final Proxyed fpy = new ObjectTest();
Thread t = new Thread();
Proxyed py = (Proxyed) Proxy.newProxyInstance(fpy.getClass().getClassLoader(), fpy.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(fpy);
}
});
py.test();
}
}