23种设计模式-java-代理
2021/7/1 20:51:29
本文主要是介绍23种设计模式-java-代理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
模式概述:
让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
使用场景:
1.延迟初始化 (虚拟代理)。 如果你有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。
2.访问控制 (保护代理)。 如果你只希望特定客户端使用服务对象, 这里的对象可以是操作系统中非常重要的部分, 而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。
3.本地执行远程服务 (远程代理)。 适用于服务对象位于远程服务器上的情形。
4.记录日志请求 (日志记录代理)。 适用于当你需要保存对于服务对象的请求历史记录时。 代理可以在向服务传递请求前进行记录。
5. 智能引用。 可在没有客户端使用某个重量级对象时立即销毁该对象。
代码样例(静态代理):
代码背景:在不改变源码的情况下,分析相关业务接口的耗时情况(接口调用前、后记录时间)并对接口的调用记录日志。代理与装饰者模式非常相像。
/** * 被代理对象接口 */ public interface OrderService { Map<String,String> getOrderInfoByOrderId(long orderId); }
/** * 被代理对象接口实现 */ public class OrderServiceImpl implements OrderService{ @Override public Map<String, String> getOrderInfoByOrderId(long orderId) { System.out.println("被代理对象执行方法,orderId="+orderId); Map<String,String> map = new HashMap<>(); map.put("orderId",String.valueOf(orderId)); map.put("orderName","灰机"); return map; } }
/** * 代理--时间 */ public class OrderServiceTimeProxy implements OrderService{ private OrderService orderService; public OrderServiceTimeProxy(OrderService orderService) { this.orderService = orderService; } @Override public Map<String, String> getOrderInfoByOrderId(long orderId) { Map<String,String> map = null; System.out.println("时间代理----before--time:"+System.currentTimeMillis()); map = orderService.getOrderInfoByOrderId(orderId); System.out.println("时间代理----after--time:"+System.currentTimeMillis()); return map; } }
/** * 代理--日志 */ public class OrderServiceLogProxy implements OrderService{ private OrderService orderService; public OrderServiceLogProxy(OrderService orderService) { this.orderService = orderService; } @Override public Map<String, String> getOrderInfoByOrderId(long orderId) { Map<String,String> map = null; System.out.println("日志代理----before"); map = orderService.getOrderInfoByOrderId(orderId); System.out.println("日志代理----after"); return map; } }
/** * 代理测试 */ public class TestProxy { public static void main(String[] args) { //静态代理 System.out.println("静态代理:"); OrderService orderService = new OrderServiceLogProxy(new OrderServiceTimeProxy(new OrderServiceImpl())); orderService.getOrderInfoByOrderId(1001l); // System.out.println(); // System.out.println(); // System.out.println(); // System.out.println("动态代理:"); // //动态代理 // OrderService orderService2 = new OrderServiceImpl(); // OrderService orderServiceDynamicProxy = (OrderService) DynamicProxyFactory.createProxy(orderService2); // Map<String,String> map = orderServiceDynamicProxy.getOrderInfoByOrderId(1002l); // System.out.println("接口返回信息:"+map.toString()); } }
测试结果:
此案例中是对orderService接口的getOrderInfoByOrderId()方法进行了代理;如果想要对orderService接口中的其他方法也设置代理,甚至对其他接口也设置日志和时间的代理,那么就需要增加很多代理类,因为静态代理类中代理对象和代理对象的方法都是已知固定的;只能代理指定的接口。因此就有了对应的动态代理,动态代理是动态生成代理类,而不是事先编码好代理类;动态代理和静态代理都是为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息;静态代理是事先编码好代理类,动态代理是程序运行时,动态生成代理类load到内存中。
JDK中的动态代理,生成代理对象需要传入3个参数,第一个是被代理对象的类加载器,第二个参数是被代理对象实现的接口,第三个参数InvocationHandler,可以理解是代理的实现逻辑。动态代理的生成是在程序运行时进行动态生成的,是操作字节码生成动态代理load到内存中的,生成的代理类会包含第二个参数中的接口数组的所有方法,方法内部的逻辑是调用第三个参数InvocationHandler的invoke方法;InvocationHandler的invoke方法通过反射调用到被代理对象的方法。注意JDK的代理的对象必须是实现接口 类;以下是JDK的代理的代码样例:
/** * 动态代理工厂--日志 */ public class DynamicProxyFactory { public static <T> Object createProxy(T t){ return Proxy.newProxyInstance(t.getClass().getClassLoader(),t.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object o; System.out.println("动态代理--日志--before"); o = method.invoke(t,args); System.out.println("动态代理--日志--after"); return o; } }); } }
/** * 代理测试 */ public class TestProxy { public static void main(String[] args) { //静态代理 // System.out.println("静态代理:"); // OrderService orderService = new OrderServiceLogProxy(new OrderServiceTimeProxy(new OrderServiceImpl())); // orderService.getOrderInfoByOrderId(1001l); // System.out.println(); // System.out.println(); // System.out.println(); // System.out.println("动态代理:"); //动态代理 OrderService orderService2 = new OrderServiceImpl(); OrderService orderServiceDynamicProxy = (OrderService) DynamicProxyFactory.createProxy(orderService2); Map<String,String> map = orderServiceDynamicProxy.getOrderInfoByOrderId(1002l); System.out.println("接口返回信息:"+map.toString()); } }
测试结果:
这篇关于23种设计模式-java-代理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)