静态代理
角色
- 公共接口:
封装了需要被代理的方法 - 真实对象:
被代理方 - 代理对象:
代理方
UML类图
代理对象持有对真实对象的引用,并且是一种一一对应的引用,此二者都实现公共接口(即实现需要被代理的方法),代理对象可以自行决定被代理对象的方法以何种方式执行、以及执行前后分别还需执行何种逻辑。
例子代码
- 公共接口:
public interface Subject {
void request();
}
- 真实对象:
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("From real subject");
}
}
- 代理对象
public class ProxySubject implements Subject{
private RealSubject realSubject;
@Override
public void request() {
this.preRequest();
if(null == realSubject){
realSubject = new RealSubject();
}
realSubject.request();
this.postRequest();
}
private void preRequest(){
}
private void postRequest(){
}
}
- 调用方式
public class Client {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
动态代理
动态代理需要jdk动态代理API的支持,本质是动态创建代理类和代理对象。
- InvocationHandler:调用处理器
在调用处理器中定义代理对象的方法执行逻辑(通过实现invoke方法),调用处理器持有一个Object引用可以保存所有对象。 - Proxy:用于动态创建代理类和代理对象
代码示例
public class VectorProxy<T> implements InvocationHandler{
private T proxyObj;
public VectorProxy(T proxyObj) {
this.proxyObj = proxyObj;
}
public T createProxyObject(Object obj){
Class<?> classType = obj.getClass();
return (T)Proxy.newProxyInstance(classType.getClassLoader(),classType.getInterfaces(),new VectorProxy(obj));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling: " + method);
if(null != args){
for (Object object: args){
System.out.println(object);
}
}
Object object = method.invoke(proxyObj,args);
System.out.println("after calling: " + method);
System.out.println(object == null);
return object;
}
public static void main(String[] args) {
List v = new VectorProxy<List>(new Vector<>()).createProxyObject(new Vector<>());
v.add("a");
v.add("b");
}
}