静态代理和动态代理
所谓代理,可以认为是 客户无法直接与服务端交流,那么就需要一个媒介来处理他们之间的会面。思想比较简单,但是遇到真实情况下,静态代理比较容易理解,动态代理值得学习,想起以前别人的一些程序还是比较容易理解。
一)静态代理
1:
public abstract class Subject
{
public abstract void request();
}
2:
public class RealSubject extends Subject
{
public void request()
{
System.out.println("From real subject.");
}
}:
3:
public class ProxySubject extends Subject
{
private RealSubject realSubject; //代理角色内部引用了真实角色
public void request()
{
this.preRequest(); //在真实角色操作之前所附加的操作
if(null == realSubject)
{
realSubject = new RealSubject();
}
realSubject.request(); //真实角色所完成的事情
this.postRequest(); //在真实角色操作之后所附加的操作
}
private void preRequest()
{
System.out.println("pre request");
}
private void postRequest()
{
System.out.println("post request");
}
}
4:
public class Client
{
public static void main(String[] args)
{
Subject subject = new ProxySubject();
subject.request();
}
}
二)动态代理
1:
public interface Subject
{
public void request();
}
2:
public class RealSubject implements Subject
{
public void request()
{
System.out.println("From real subject!");
}
}
3:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象
* 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要
* 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后
* 加入自己的一些额外方法。
*
*/
public class DynamicSubject implements InvocationHandler
{
private Object sub;
public DynamicSubject(Object obj)
{
this.sub = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("before calling: " + method);
method.invoke(sub, args);
System.out.println(args == null);
System.out.println("after calling: " + method);
return null;
}
}
4:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;
public class VectorProxy implements InvocationHandler
{
private Object proxyObj;
public VectorProxy(Object obj)
{
this.proxyObj = obj;
}
public static Object factory(Object obj)
{
Class<?> classType = obj.getClass();
return Proxy.newProxyInstance(classType.getClassLoader(),
classType.getInterfaces(), new VectorProxy(obj));
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("before calling: " + method);
if(null != args)
{
for(Object obj : args)
{
System.out.println(obj);
}
}
Object object = method.invoke(proxyObj, args);
System.out.println("after calling: " + method);
return object;
}
public static void main(String[] args)
{
List v = (List)factory(new Vector());
System.out.println(v.getClass().getName());
v.add("New");
v.add("York");
System.out.println(v);
v.remove(0);
System.out.println(v);
}
}
5:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client
{
public static void main(String[] args)
{
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSubject);
Class<?> classType = handler.getClass();
// 下面的代码一次性生成代理
Subject subject = (Subject) Proxy.newProxyInstance(classType
.getClassLoader(), realSubject.getClass().getInterfaces(),
handler);
subject.request();
System.out.println(subject.getClass());
}
}
Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。
其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。可以这样想象:编译期间我们不知道有多少类,只有在运行期间利用反射机制动态的生成一些class。这就是所谓的动态代理,表面做到了灵活性,但是我始终觉得比较耗资源。