Java动态代理(代理模式/委托模式)
1、代理的定义
为其他对象提供一种代理以控制对这个对象的访问。
2、代理的使用场景
在某些情况下,我们不希望或是不能直接访问对象 A,而是通过访问一个中介对象 B,由 B 去访问 A 达成目的,这种方式我们就称为代理。
这里对象 A 所属类我们称为委托类,也称为被代理类,对象 B 所属类称为代理类。
代理优点有:
- 隐藏委托类的实现
- 解耦,不改变委托类代码情况下做一些额外处理,比如添加初始判断及其他公共操作
根据程序运行前代理类是否已经存在,可以将代理分为静态代理和动态代理。
3、静态代理
代理者的代码由程序员自己或通过一些自动化工具生成固定的代码再对其进行编译,代码运行前代理类的class编译文件就已经存在。
//抽象主题类
public abstract class Subject{
public abstract void operate();
}
//真实主题类-->委托类
public class RealSubject extends Subject{
@Override
public void operate() {
System.out.println("real subject");
}
}
//代理主题类-->代理类
public class ProxySubject extends Subject{
private RealSubject mSubject;
public ProxySubject(RealSubject subject){
mSubject = subject;
}
@Override
public void operate() {
mSubject.operate();
}
}
public class Client{
public static void main(String[] args){
RealSubject real = new RealSubject();
ProxySubject proxy = new ProxySubject(real);
proxy.operate();
}
}
4、动态代理
通过反射机制动态的生成代理者的对象,代理谁只有在执行时才知道。java提供了一个便捷的动态代理接口InvocationHandler,实现该接口需要重写invoke()方法。
实现动态代理包括三步:
- 新建委托类;
- 实现InvocationHandler接口,这是负责连接代理类和委托类的中间类必须实现的接口;
- 通过Proxy类创建代理类对象。
4.1、新建委托类
//抽象主题类
public abstract class Subject{
public abstract void operate();
}
//真实主题类-->委托类
public class RealSubject extends Subject{
@Override
public void operate() {
System.out.println("real subject");
}
}
4.2、实现InvocationHandler接口
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy() {}
public DynamicProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = method.invoke(target, args);
return obj;
}
}
4.3、通过Proxy类静态函数生成代理对象
public class Client{
public static void main(String[] args){
//创建一个真实对象
RealSubject real = new RealSubject();
//创建一个动态代理对象
DynamicProxy proxy = new DynamicProxy(real);
//获取被代理类的ClassLoader对象
ClassLoader loader = real.getClass().getClassLoader();
//动态构造一个代理对象
Subject subject = (Subject)(Proxy.newProxyInstance(loader,new Class[]{Subject.class},proxy));
//调用方法
subject.operate();
}
}
动态代理相当于双层的静态代理,开发者提供委托类RealSubject,程序生成代理类Subject,开发者同时实现一个InvocationHandler的子类DynamicProxy,子类DynamicProxy连接代理类Subject和委托类RealSubject,它是代理类Subject的委托类,委托类RealSubject的代理类。用户通过调用调用代理类程序生成代理类Subject的对象,Subject调用转发给DynamicProxy,DynamicProxy再转发给RealSubject。
参考:公共技术点之 Java 动态代理
http://a.codekk.com/detail/Android/Caij/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8B%20Java%20%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86