之前我们实现了静态代理设计模式。可以看到静态代理存在一个问题:如果抽象主题的接口发生变化,代理类也得做出相应的修改。而动态代理不需要。
动态代理主要有两种实现方式,一种是JDK动态代理,继承InvocationHandler
接口;另一种是字节码动态代理,使用cglib等基于字节码的动态代理框架。
和静态代理一样,抽象主题接口提供对外的方法。
public interface Subject {
// the method that both real subject and proxy subject should have
void request();
void doSomeOther();
}
真实主题
同静态代理一样,是抽象主题接口的实现类。
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("real subject do the request");
}
@Override
public void doSomeOther() {
System.out.println("real subject do some other thing");
}
}
代理处理器
这个是JDK动态代理的核心。
- 继承
InvocationHandler
接口; - 实现
invoke
方法; - 返回代理对象
public class MyInvocationHandler implements InvocationHandler {
// the target object
private Object target;
public MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do something before");
Object result = method.invoke(target,args);
System.out.println("do something after");
return result;
}
public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
target.getClass().getInterfaces(),
this);
}
客户端
客户端类稍有变化。需要从InvocationHandler
的实现类调用getProxy
方法得到代理对象。
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
MyInvocationHandler invocationHandler = new MyInvocationHandler(subject);
Subject proxy = (Subject) invocationHandler.getProxy();
proxy.request();
proxy.doSomeOther();
}
}
感谢您的阅读,若您喜欢,可以点击下方的的“推荐”支持我。谢谢!
也可以关注我的慕课账号,会经常更新Java、算法、Vue开发方面的文章哦~