前提条件
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 方法
- 代理类的内部方法间的调用时,代理不生效