代理
技术要点:1、使用接口规范代理类和被代理类的行为
2、通过使用代理类实现对被代理类的调用
解决问题:整体-部分
public interface ActionInterf{
boolean open();
boolean close();
}
public class Door implements ActionInterf{
private isClose = ture;
public boolean open(){
if(isClose) isClose = false;
return isClose;
}
public boolean close(){
if(!isClose) isClose = ture;
return isClose;
}
}
//proxy
public class House implements ActionInterf{
private ActionInterf proxied = new Door(); //这里只能代理Door
public boolean openDoor(){
return proxied.open();
}
public boolean close(){
return proxied.closeDoor();
}
}
//main
House house = new House();
house.open();
house.close();
动态代理
技术要求:我(代理类)能够代理所有需要代理的类(具有某种行为规范的所有具体实现类),并能够调用相应的方法
技术要点:1、通过动态传入需要代理的类
解决问题:根据实际需要,代理所希望代理的具体类
public class Window implements ActionInterf{
private isClose = ture;
public boolean open(){
if(isClose) isClose = false;
return isClose;
}
public boolean close(){
if(!isClose) isClose = ture;
return isClose;
}
}
//dynamicProxy
public class DynamicProxyHouse implements ActionInterf{
private ActionInterf proxied; //代理所有需要代理的类
public void DynamicHouse(){}
public setProxied(ActionInterf proxied){ this.proxied = proxied;}
public boolean open(){
return proxied.open();
}
public boolean close(){
return proxied.close();
}
}
//main
DynamicProxyHouse proxyHouse = new DynamicProxyHouse();
proxyHouse.setProxied(new Door());
proxyHouse.open();
proxyHouse.close();
proxyHouse.setProxied(new Window());
proxyHouse.open();
proxyHouse.close();
反射代理
技术要点:1、使用Java的反射机制
2、使用Java提供的Proxy类
3、实现Java的InvocationHandler接口或其某一个子类
解决问题:使用反射机制实现动态代理,实现将所有调用重定向到调用处理器。同时,我们不需要实现代理类,简化了工作。
class DynamicProxyHandler implements InvocationHandler{ //能不能使用泛型
private Object proxied;
public void DynamicProxyHandler(Object proxied){this.proxied = proxied;}
public Object invoke(Object proxy, Method method, Object[] args){
//proxy用来区分请求的来源,但大多情况我们并不需要关心,即proxy没有用
//...
return method.invoke(proxied, args);
}
}
//main
//方法一:
DynamicProxyHandlerDoor doorHandler = new DynamicProxyHandler(new Door());
//proxy的Class
Class proxyClass = Proxy.getProxyClass(ActionInterf.class.getClassLoader(), //类加载器
new Class[]{ActionInterf.class}); //代理类要实现的接口列表
//proxy的实例
ActionInterf proxyDoor = (Door)proxyClass.getConstructor(new Class[]{InvocationHandler.class}
).newInstance(new Object[]{doorHandler});
proxyDoor.open(); //去调用invoke()
proxyDoor.close();
//方法二:最好使用这种方式
DynamicProxyHandlerDoor = new DynamicProxyHandler(new Door());
ActionInterf proxyDoor = (ActionInterf)Proxy.newProxyInstance(
ActionInterf.class.getClassLoader(),
new Class[]{ActionInterf.class}, //代理类要实现的接口列表
DynamicProxyHandlerDoor); //指定调用处理程序
proxyDoor.open(); //去调用invoke()
proxyDoor.close();
反射代理实现原理:猜测
Proxy.newProxyInstance()
编译器首先创建一个相应接口的代理类ProxyActionInterf,
class ProxyActionInterf{
InvocationHandler handler = null;
void ProxyActionInterf(InvocationHandler handler){ this.handler = handler;}
public boolean open(){
handler.invoke(this, handler.getProxied().getClass().getDecriXXXXMethod("open", null), args);
}
...
}
|
|