代理模式
使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法 .
来源于这篇博客
以下例子来源于大神狂神!!!
1、静态代理

1. Rent接口,负责出租房子的人和中介共同需要干的事出租房子
| |
| public interface Rent { |
| |
| |
| public void rent(); |
| |
| } |
2. Proxy表示中介去继承租房的接口
- 房东只需要把房子交给中介就行了,有中介代理,中介有些自己的事情要做....
| @Component(value = "proxy") |
| public class Proxy implements Rent{ |
| @Autowired |
| @Qualifier("host") |
| private Host host; |
| |
| public Proxy() { |
| } |
| |
| public Proxy(Host host) { |
| this.host = host; |
| } |
| |
| @Override |
| public void rent() { |
| lookHouse(); |
| host.rent(); |
| signContract(); |
| harvestFees(); |
| } |
| |
| public void lookHouse(){ |
| System.out.println("看" + host.getHostName() +"的房子"); |
| } |
| |
| public void signContract(){ |
| System.out.println("签合同"); |
| } |
| |
| public void harvestFees(){ |
| System.out.println("收中介费"); |
| } |
| |
| } |
3. 房东Host,需要出租房屋,他就只干一件事,租房子
| @Component(value = "host") |
| public class Host implements Rent{ |
| |
| private String hostName; |
| |
| public String getHostName() { |
| return hostName; |
| } |
| |
| public void setHostName(String hostName) { |
| this.hostName = hostName; |
| } |
| |
| @Override |
| public void rent() { |
| System.out.println("房东要出租房"); |
| } |
| } |
| |
4. 需要租房的人,People,需要找中介租房,不直接联系房东,由中介全权代理
| |
| public class People { |
| |
| @Test |
| public void makeHouse(){ |
| |
| ApplicationContext context = new AnnotationConfigApplicationContext(SsyConfig.class); |
| |
| Host host = context.getBean("host", Host.class); |
| host.setHostName("水三丫"); |
| Proxy proxy = context.getBean("proxy", Proxy.class); |
| proxy.rent(); |
| |
| } |
| } |
| |
| |
| 看水三丫的房子 |
| 房东要出租房 |
| 签合同 |
| 收中介费 |
| |
| Process finished with exit code 0 |
静态代理的缺点:一个真实的角色会参数一个代理角色,代码量会翻倍,需要动态代理来解决
2、动态代理
利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对象),代理的是接口(Interfaces),不是类(Class),也不是抽象类。在运行时才知道具体的实现,spring aop就是此原理。
参考一笑而过者也博客
2.1 需要了解两个类
| @CallerSensitive |
| public static Object newProxyInstance(ClassLoader loader, |
| Class<?>[] interfaces, |
| InvocationHandler h) |
| throws IllegalArgumentException |
-
loader: 用哪个类加载器去加载代理对象
-
interfaces:动态代理类需要实现的接口
-
h:动态代理方法在执行时,会调用h里面的invoke方法去执行
- InvocationHandler接口:调用处理程序
2.2 测试
| public interface UserService { |
| |
| public void add(); |
| |
| public void update(); |
| |
| public void delete(); |
| |
| public void query(); |
| } |
| public class UserServiceImpl implements UserService{ |
| @Override |
| public void add() { |
| System.out.println("增加了一个用户"); |
| } |
| |
| @Override |
| public void update() { |
| System.out.println("更新了一个用户"); |
| } |
| |
| @Override |
| public void delete() { |
| System.out.println("删除了一个用户"); |
| } |
| |
| @Override |
| public void query() { |
| System.out.println("查询了一个用户"); |
| } |
| } |
- 实现该InvocationHandler接口的通过反射获取代理类的类
| @Component("proxyInvocationHandler") |
| public class ProxyInvocationHandler implements InvocationHandler { |
| |
| private Object target; |
| |
| public Object getTarget() { |
| return target; |
| } |
| |
| public void setTarget(Object target) { |
| this.target = target; |
| } |
| |
| |
| public Object getProxy(){ |
| return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); |
| } |
| |
| |
| |
| @Override |
| public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
| |
| System.out.println(method.getName()); |
| before(); |
| Object result = method.invoke(target, args); |
| after(); |
| return result; |
| } |
| |
| public void before(){ |
| System.out.println("操作之前打印日志"); |
| } |
| |
| |
| public void after(){ |
| System.out.println("操作之后打印日志"); |
| } |
| } |
| public class UserServlet { |
| |
| @Test |
| public void test(){ |
| ApplicationContext context = new AnnotationConfigApplicationContext(SsyConfigService.class); |
| |
| UserServiceImpl userServiceImpl = context.getBean("userService", UserServiceImpl.class); |
| ProxyInvocationHandler pih = context.getBean("proxyInvocationHandler", ProxyInvocationHandler.class); |
| |
| pih.setTarget(userServiceImpl); |
| |
| |
| UserService proxy = (UserService) pih.getProxy(); |
| |
| proxy.update(); |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)