代理
关于代理的理解:火车站(委托对象)可以买票也可以退票,取票点(代理对象)只能买票
定义:给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象。
静态代理
接口
public interface Interface {
void dosomething();
void somethingElse(String args);
}
委托对象
public class RealObject implements Interface {
public void dosomething(){
System.out.println("dosomething");
}
public void somethingElse(String args){
System.out.println("somethigElse "+args);
}
}
代理对象
public class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied){
this.proxied=proxied;
}
public void dosomething(){
System.out.println("SimpleProxy dosomethig");
proxied.dosomething();
}
public void somethingElse(String args){
System.out.println("SimpleProxy somethingElse "+args);
proxied.somethingElse(args);
}
}
实现
public class SimpleProxyDemo {
public static void consumer(Interface iface){
iface.dosomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args){
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
动态代理
在Java的动态代理机制中,有两个重要的类和接口,一个是InvocationHandler (interface)
,一个是Proxy (Class)
。
当我们通过动态代理对象调用一个方法的时候,这个方法的调用就会被转为由InvocationHandler
这个接口的invoke
方法来进行调用。
利用动态代理改写上述静态代理,接口和委托对象不变
动态代理实现
public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied){
this.proxied=proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("**** Proxy: "+proxy.getClass()+",method: "+method+" , args: "+args);
if(args!=null)
for(Object arg:args)
System.out.println(" "+arg);
return method.invoke(proxied,args);
}
}
关于invoke
- Object proxy 委托对象
- Method method 调用委托对象的某个方法的Method对象
- Object[] args 调用真实对象某个方法时接受的参数
Client
public class SimpleDynamicProxy {
public static void consume(Interface iface){
iface.dosomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args){
RealObject realObject=new RealObject();
consume(realObject);
Interface proxy=(Interface) Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{Interface.class},
new DynamicProxyHandler(realObject)
);
consume(proxy);
}
}