代理模式
定义: 调用者使用代理类来调用目的接口的对象
使用场景: 当调用者不想直接调用目的接口对象或者调用者调用目的接口对象存在困难时
实现一(静态代理):
创建代理类来实现
优点: 任何实现目的接口的对象都可以通过代理类来访问,增加了代码的通用性
缺点: 当目的接口发生更改时,代理类 也得随之改变;当代理对象非常多时就会显得代理对象特别臃肿
目的接口:
public interface Subject {
void visit();
}
目的接口实现类(代理对象):
public class RealSubject implements Subject {
@Override
public void visit() {
System.out.println("香格里拉皇子");
}
}
代理类:
public class ProxySubject implements Subject {
private Subject subject;
//以构造注入的方式将目的接口的实现类注入
public ProxySubject(Subject subject) {
this.subject = subject;
}
@Override
public void visit() {
subject.visit();
}
}
实现二(动态代理):
静态代理是直接创建代理类,动态代理是在调用时根据代理对象动态创建代理类
优点: 在实现代理模式的基础上避免了静态代理中代理类接口过多的问题
缺点: 动态代理使用反射实现的,在一定程度上效率过低
目的接口:
public interface Subject {
void visit();
}
目的接口实现类(代理对象):
public class RealSubject implements Subject {
@Override
public void visit() {
System.out.println("人世间子");
}
}
动态代理类:
public class DynamicProxy implements InvocationHandler {
private Object object;
//将要代理的对象通过构造注入的方式注入进来
public DynamicProxy(Object o) {
this.object = o;
}
/**
* 创建代理类
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = method.invoke(object, args);
return o;
}
}
测试:
public class ProxyTest {
public static void main(String[] args) {
//静态代理
ProxySubject subject = new ProxySubject(new RealSubject());
subject.visit();
//动态代理
RealSubject subject1 = new RealSubject();
DynamicProxy proxy = new DynamicProxy(subject1);
ClassLoader classLoader = subject1.getClass().getClassLoader();
//参数一: 代理对象的类加载器; 参数二: 目的接口的一组实现; 参数三: 代理类实例化对象
Subject subject2 = (Subject)Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
subject2.visit();
}
}
Wish me luck!