模式定义
为其他对象提供一种代理以控制对这个对象的访问。
模式结构
模式结构
代码实现
public interface Subject {
void print();
}
public class RealSubject implements Subject {
public void print() {
System.out.println("我不想打印日志,让我的代理类来打印吧");
}
}
public class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
public void print() {
System.out.println("我是苦逼代理类,我来打印日志,开始打印日志");
subject.print();
System.out.println("打印日志完成,我好累!");
}
}
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
Subject proxy = new Proxy(subject);
proxy.print();
}
}
分类
安全代理
屏蔽对真实角色的直接访问。远程代理
通过代理类处理远程方法调用(RMI)延迟加载
先加载轻量级的代理对象,真正需要再加载真实对象。
思考
模式本质:控制对象访问。
开发中的应用场景
需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理。
需要按照需要创建开销很大的对象的时候,可以使用需代理。
需要控制对原始对象的访问的时候,可以使用保护代理。
需要在访问对象执行一些附加操作的时候,可以使用智能指引代理。
动态代理工具类
JDK动态代理
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return null;
}
private void after() {
System.out.println("before:");
}
private void before() {
System.out.println("after:");
}
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
this);
}
public static void main(String[] args) {
Hello cglib = new DynamicProxy(new HelloImpl()).getProxy();
cglib.say();
}
}
CGLib动态代理
public class CGLibProxy implements MethodInterceptor {
//私有化构造器
private CGLibProxy() {
}
//静态类部类
private static class singletonClass {
private static final CGLibProxy instance = new CGLibProxy();
}
//全局访问点
public static CGLibProxy getInstance() {
return singletonClass.instance;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(o, objects);
after();
return result;
}
private void after() {
System.out.println("before:");
}
private void before() {
System.out.println("after:");
}
public <T> T getProxy(Class<T> clazz) {
return (T) Enhancer.create( clazz, this);
}
public static void main(String[] args) {
Hello hello = CGLibProxy.getInstance().getProxy(HelloImpl.class);
hello.say();
}
}