动态代理是一种设计模式,在该模式中,代理对象在运行时动态地生成,而不是在编译时静态地生成。这使得一种类型的对象可以在运行时表现为另一种类型。在Java中,动态代理主要通过 java.lang.reflect.Proxy
类实现。以下内容将尝试深入浅出地解释动态代理。
浅出理解:戏剧与角色扮演
想象你在看一出戏,主角突然生病不能表演了。现在,一个替身演员(代理)出现了。这个代理完全了解主角应当如何行动和说话,并按照同样的脚本进行表演。观众(调用者)几乎感觉不出差异。
- 戏剧(Your Application):你的应用程序
- 主角(Real Object):你原本需要的对象
- 替身演员(Proxy Object):动态代理对象
- 脚本(Interface):定义了主角和代理如何表演的规则
- 观众(Client Code):调用对象(主角或代理)的代码
理论知识:动态代理的组成
- 接口(Interface):动态代理类需要实现的接口列表。
- 实际对象(Real Object):实现该接口的实际对象。
- 代理对象(Proxy Object):动态生成,用于中介或代表实际对象。
实践操作:Java的动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Actor {
void act();
}
class RealActor implements Actor {
public void act() {
System.out.println("Real actor is acting.");
}
}
class ActorInvocationHandler implements InvocationHandler {
private Object target;
public ActorInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Proxy actor gets ready.");
Object result = method.invoke(target, args);
System.out.println("Proxy actor finishes.");
return result;
}
}
public class Main {
public static void main(String[] args) {
Actor realActor = new RealActor();
Actor proxyActor = (Actor) Proxy.newProxyInstance(
realActor.getClass().getClassLoader(),
realActor.getClass().getInterfaces(),
new ActorInvocationHandler(realActor)
);
proxyActor.act();
}
}
输出:
Proxy actor gets ready.
Real actor is acting.
Proxy actor finishes.
优点与应用
- 灵活性和扩展性:在不改变原有对象的基础上,通过代理对象实现新功能。
- 解耦和职责分离:可以把日志、安全等其他关注点与业务逻辑分离。
深入理解:动态与静态代理的区别
- 静态代理:在编译时代理类就已经创建。
- 动态代理:在运行时根据需要动态