抽象主题接口:
public interface Subject {
void doSomething();
}
真实主题类:
public class RealSubject implements Subject {
public void doSomething() {
System.out.println("RealSubject do something");
}
}
代理者:
public class SubjectProxy implements Subject {
private RealSubject realSubject = null;
@Override
public void doSomething() {
beforeDoSomething();
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.doSomething();
afterDoSomething();
}
private void beforeDoSomething() {
System.out.println("before doing something");
}
private void afterDoSomething() {
System.out.println("after doing something");
}
}
调用者:
public class Client {
public static void main(String[] args) {
Subject subject = (Subject) new SubjectProxy();//使用SubjectProxy代替Subject
subject.doSomething(); //代理者代替真实者做事情
}
}
静态代理的局限性
可以看到,静态代理让调用者不用再直接持有操作者的引用,而是将一切操作交由代理者去完成。但是静态代理也有它的局限性:
-
如果需要增加一个需要代理的方法,代理者的代码也必须改动进而适配新的操作;
-
如果需要代理者代理另外一个操作者,同样需要对代理者进行扩展并且更加麻烦。
可能有人想到可以用策略模式和工厂模式分别解决上面两个问题,但是,有没有更加巧妙的方法呢?首先,我们了解一下 Java 代码的执行过程。
理解 Java 代码执行流程
要从根本上理解动态代理的实现原理,得先从 Java 代码的执行流程说起:

JVM 在运行 .class 文件之前,首先通过 ClassLoader 将 .class 文件以二进制的形式解析并生成实例以供调用,我们的代码执行逻辑是在 JVM 的运行期系统中进行工作的,那么,我们可不可以在自己的代码里面按照 .class 的格式生成自己的 .class 文件,进而调用自定义的 ClassLoader 将其加载出来呢?答案是肯定的,这样我们就可以动态地创建一个类了。
