设计模式 -- Proxy(代理模式)
代理模式(Proxy)
- 在面向对象系统中,有些对象由于某种原因(比如对象创建开销很大或者某些操作需要安全控制或者需要进程外访问等),直接访问会给使用者、或者系统结构带来很多的麻烦。
为其他对象提供一种代理以控制(隔离,使用接口)对这个对象的访问。
Spring的AOP就是一种代理模式、对某个类方法进行代理、外部调用时根据接口调用、实际调用的是增强了的代理方法
代码
对每个类中的方法进行代理、采用JDK代理
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
interface Person {
void show();
}
class XiaoMing implements Person {
@Override
public void show() {
System.out.println("XiaoMing");
}
}
public class Proxy {
@Test
public void T1() {
Person xiaoMing = new XiaoMing();
Person xiaoMingProx = (Person) java.lang.reflect.Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强");
Object invoke = method.invoke(xiaoMing, args);
System.out.println("后置增强");
return invoke;
}
});
xiaoMingProx.show();
}
}
封装
可以将JDK代理封装起来
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public interface YsqProxy {
/**
* 前置增强
* @param args 代理方法的参数数组
* @return
*/
void before(Object... args);
/**
* 后置增强
* @param result 代理方法的返回结果、无则返回null
* @param args 代理方法的参数数组
* @return
*/
void after(Object result, Object... args);
/**
* 获取代理对象
* @return 返回代理对象
*/
default Object getProxyObject(Object o) {
return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
before(args);
// 代理方法调用
Object invoke = method.invoke(o, args);
// 后置增强
after(invoke, args);
// 返回代理方法返回值
return invoke;
}
});
}
}
使用方法、创建一个代理对象的代理类、继承YsqProxy、实现前置增强和后置增强、调用getProxyObject返回对应的增强代理对象即可
public class XiaoMingProxy implements YsqProxy{
@Override
public void before(Object... args) {
System.out.println("前置增强");
return null;
}
@Override
public void after(Object result, Object... args) {
System.out.println("后置增强");
return null;
}
}
public class Main {
public static void main(String[] args) throws Exception{
Person xiaoMing = new XiaoMing();
XiaoMingProxy xiaoMingProxy = new XiaoMingProxy();
Person person = (Person) xiaoMingProxy.getProxyObject(xiaoMing);
person.show("test", "El Psy Congroo!");
}
}
要点总结
“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方案。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的Proxy对象便是解决这一问题的常用手段。
具体Proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组建模块提供抽象代理层,在架构层次对对象做proxy
proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库