设计模式——代理模式

代理模式(Proxy Pattern)定义如下:

为其他对象提供一种代理以控制对这个对象的访问

代理模式的通用类图

其基本实现代码如下:

1
2
3
public interface Subject {
void request();
}
1
2
3
4
5
6
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("doing sth...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Proxy implements Subject {
private Subject subject = null;

public Proxy(Subject subject) {
this.subject = subject;
}

@Override
public void request() {
before();
subject.request();
after();
}

private void before() {}

private void after() {}
}

调用一下:

1
2
3
4
public static void main(String[] args) {
Proxy proxy = new Proxy(new RealSubject());
proxy.request();
}

控制台:

1
doing sth...

在我看来代理模式最有价值的地方在于能”夹带私活”,即在执行代理对象的业务方法的前后执行前置、后置方法。

当然他也可以实现其他的接口,一并把其他接口中的方法执行了。

这其实和切面编程很像,AOP 核心就是采用了动态代理机制。

动态代理

动态代理通用类图

这边简单实现一下,依然沿用上面的SubjectRealSubject类,只不过动态代理不再需要写Proxy代理类,而是用反射动态生成的方式取而代之。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
private Object target = null;

public MyInvocationHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(this.target, args);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader classLoader, Class<?>[] interfaces,
InvocationHandler handler) {
if (true) {
// (new BeforeAdvice()).exec();
System.out.println("my dynamic before method run.");
}
return (T) Proxy.newProxyInstance(classLoader, interfaces, handler);
}
}

这边简化了一下,没有实现Advice相关类。

调用:

1
2
3
4
5
6
7
public static void main(String[] args) {
Subject subject = new RealSubject();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(subject);
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(), myInvocationHandler);
proxy.request();
}

控制台:

1
2
my dynamic before method run.
doing sth...

设计模式——代理模式
https://honosv.github.io/2023/09/19/设计模式——代理模式/
作者
Nova
发布于
2023年9月19日
许可协议