前提条件
public interface Animal {
    void say();
    void run(String addr);
}
public class Dog implements Animal {
    @Override
    public void say() {
        System.out.println("汪汪汪");
    }
    @Override
    public void run(String addr) {
        say();
        System.out.println("狗在" + addr + "跑");
    }
}
代理模式示例
public class DogProxy implements Animal {
    private Dog dog;
    public DogProxy(Dog dog) {
        this.dog = dog;
    }
    @Override
    public void say() {
    }
    @Override
    public void run(String addr) {
        System.out.println("跑之前");
        try {
            dog.run(addr);
        } finally {
            System.out.println("跑之后");
        }
    }
}
// 调用
new DogProxy(new Dog()).run("路上");
Java 动态代理示例
public class InvokeHandler implements InvocationHandler {
    private Object object;
    public InvokeHandler(Object object) {
        this.object = object;
    }
    /**
     * @param proxy 相当于代理类的 this
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用之前");
        try {
            return method.invoke(object, args);
        } finally {
            System.out.println("调用之后");
        }
    }
}
// 调用
InvokeHandler handle = new InvokeHandler(new Dog());
Animal animal = (Animal) Proxy.newProxyInstance(
                this.getClass().getClassLoader(), Dog.class.getInterfaces(), handle);
animal.run("路上");
Java 动态代理类特性
- 类名以 $Proxy开头
- 代理类继承自 java.lang.reflect.Proxy
- 调用 Proxy.isProxyClass 方法返回 true
- 代理类严格按顺序实现所有的接口(当实现的几个接口中有重复的方法时,代理类总是从最前面的接口获取方法对象,并分派给调用处理器)
- 在代理类实例上调用其代理的接口中所声明的方法时,最终都会由调用处理器的 invoke 方法执行;此外 java.lang.Object 中的 public,非 final 方法也会分派给调用处理器 invoke 方法执行,如:hashCode,equals,toString
Java 动态代理的限制
- 只能代理接口,因此只能代理 public 方法
- 代理类的内部方法间的调用时,代理不生效