当前位置:首页 > CN2资讯 > 正文内容

设计模式--代理模式设计模式 代理

9小时前CN2资讯
代理模式

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

代理对象在客户端和目标对象之间起到中介的作用。

类型:结构型

使用场景:(1)保护目标对象,(2)增强目标对象

优点:(1)代理模式能将代理对象与真实被调用的目标对象分离,(2)一定程度上降低了系统的耦合度,扩展性好,(3)保护目标对象,(4)增强目标对象。

缺点:(1)代理模式会造成系统设计中类的数目增加,(2)在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢,(3)怎加了系统的复杂度

扩展:(1)静态代理:在代码中显示指定的代理。(2)动态代理:只能对实现了接口的类代理,并不能针对一个具体的实现类,(在jdk中,动态类无法代理一个类,但是可以代理一个接口),(3)CGLib代理,可以代理类,就是针对类实现代理,这种方法要注意 final 修饰符。

静态代理 是通过在代码中显式的定义了一个业务实现类的代理,在代理类中对同名的业务方法进行一个包装。用户通过调用代理类的,被包装过的业务方法来调用目标对象的业务方法,同时对目标的业务方法进行增强 动态代理 是通过接口中的方法名,在动态生成的代理类中,调用业务实现类的同名方法,这里需要注意一定是接口 CGLib动态代理 是通过继承来实现的,生成动态代理类就是业务类的子类,然后通过重写业务方法进行代理

Spring代理选择-扩展:(1)当Bean有实现接口时,Spring就会用JDK的动态代理,(2)当Bean没有实现接口时,Spring使用CGLib,(3)可以强制使用CGLib,(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class = "true"/>)

代理速度对比-扩展:在万次执行的情况下,JDK7和8的动态代理要比CGLib快20%左右。

  不同点 相同点 代理模式 控制访问,代理模式更加注重通过设置代理人的方式来增强目标对象的行为 实现比较相似,但目的不同 装饰者模式 为对象加上行为   不同点 代理模式 是不能改变所代理类的接口的 适配器模式 主要改变所考虑对象的接口

下面的代码,有涉及到Spring的分库,至于什么是Spring的分库,现在还不知道。

静态代理

// 每个 class 都是一个 .java 文件 public class Order { private Object orderInfo; private Integer userId; public Object getOrderInfo() { return orderInfo; } public void setOrderInfo(Object orderInfo) { this.orderInfo = orderInfo; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } } // Dao层 public interface IOrderDao { int insert(Order order); } public class OrderDaoImpl implements IOrderDao { @Override public int insert(Order order) { System.out.println("Dao层添加Order成功"); return 1; } } // servece 层 public interface IOrderService { int saveOrder(Order order); } public class OrderServiceImpl implements IOrderService { private IOrderDao iOrderDao; @Override public int saveOrder(Order order) { //Spring会自己注入,我们课程中就直接new了 iOrderDao = new OrderDaoImpl(); System.out.println("Service层调用Dao层添加Order"); return iOrderDao.insert(order); } } // 数据源 public class DataSourceContextHolder { private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>(); public static void setDBType(String dbType){ CONTEXT_HOLDER.set(dbType); } public static String getDBType(){ return (String)CONTEXT_HOLDER.get(); } public static void clearDBType(){ CONTEXT_HOLDER.remove(); } } // 静态代理 public class OrderServiceStaticProxy { private IOrderService iOrderService; public int saveOrder(Order order){ beforeMethod(order); iOrderService = new OrderServiceImpl(); int result = iOrderService.saveOrder(order); afterMethod(); return result; } private void beforeMethod(Order order){ int userId = order.getUserId(); int dbRouter = userId % 2; System.out.println("静态代理分配到【db"+dbRouter+"】处理数据"); //todo 设置dataSource; DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); System.out.println("静态代理 before code"); } private void afterMethod(){ System.out.println("静态代理 after code"); } } // 测试代码 public class Test { public static void main(String[] args) { Order order = new Order(); order.setUserId(2); OrderServiceStaticProxy orderServiceStaticProxy = new OrderServiceStaticProxy(); orderServiceStaticProxy.saveOrder(order); } }

UML类图:

动态代理

//这个例子中用到的类都在静态代理的例子中。 // 数据源 public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDBType(); } } // 动态代理: public class OrderServiceDynamicProxy implements InvocationHandler { private Object target; public OrderServiceDynamicProxy(Object target) { this.target = target; } public Object bind(){ Class cls = target.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object argObject = args[0]; beforeMethod(argObject); Object object = method.invoke(target,args); afterMethod(); return object; } private void beforeMethod(Object obj){ int userId = 0; System.out.println("动态代理 before code"); if(obj instanceof Order){ Order order = (Order)obj; userId = order.getUserId(); } int dbRouter = userId % 2; System.out.println("动态代理分配到【db"+dbRouter+"】处理数据"); //todo 设置dataSource; DataSourceContextHolder.setDBType("db"+String.valueOf(dbRouter)); } private void afterMethod(){ System.out.println("动态代理 after code"); } } // 测试类 public class Test { public static void main(String[] args) { Order order = new Order(); // order.setUserId(2); order.setUserId(1); IOrderService orderServiceDynamicProxy = (IOrderService) new OrderServiceDynamicProxy(new OrderServiceImpl()).bind(); orderServiceDynamicProxy.saveOrder(order); } }

源码示例

jdk中的 java.lang.reflect.proxy 类。

Spring 中的 ProxyFactoryBean 类,这个类的核心方法就是 getObject()方法。  或是是Spring 中 JdkDynamicAopProxy 类,也是Spring重要的类。 CglibAopProxy类。

mybatis 中的 MapperProxyFactory 类。

    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/24922.html

    分享给朋友:

    “设计模式--代理模式设计模式 代理” 的相关文章

    中国电信CN2价格表最新版下载指南:助力企业轻松选择优质网络服务

    在互联网高速发展的今天,网络服务质量已经成为企业发展的重要保障。而对于企业来说,选择一家优质、可靠、性价比高的网络服务提供商尤为重要。中国电信作为国内领先的通信运营商,始终致力于为企业提供优质的网络服务,其CN2网络更是以其稳定的性能和全面的覆盖而备受好评。为了帮助企业更好地选择适合自己的网络服务方...

    如何利用VPS挖矿赚钱:低成本高收益的加密货币挖矿指南

    VPS挖矿的基本概念 VPS挖矿是一种利用虚拟专用服务器(VPS)的计算资源进行加密货币挖矿的方式。VPS通常用于托管网站或运行应用程序,但它的计算能力也可以被用来执行挖矿算法。挖矿本质上是通过解决复杂的数学问题来验证交易并创建新的加密货币区块,作为回报,矿工会获得一定数量的加密货币。VPS挖矿特别...

    AS7473在网络数据传输中的重要性与应用探究

    AS7473简介 AS7473是一个重要的ASN编号,主要与网络数据传输和路由相关。它在信息技术领域中扮演着至关重要的角色,连接着不同的网络节点,确保数据能够顺利传输。想象一下,在这个数字化时代,数据的传输速度和准确性直接影响着我们的工作效率与信息交流。因此,AS7473的定义与重要性绝不容小觑。...

    企业云计算的首选:Oracle Cloud VPS详解及其优势

    在现代企业日益依赖云计算的背景下,Oracle Cloud VPS(虚拟专用服务器)因其强大的功能和灵活的解决方案,成为了很多企业的热门选择。简单来说,Oracle Cloud VPS通过虚拟化技术将物理服务器划分成多个独立的虚拟服务器,为用户提供了一种安全、可靠且高效的云计算体验。在这里,我将为大...

    腾讯云与Cloudflare的比较分析:助力企业数字化转型的最佳选择

    在数字化转型的浪潮下,越来越多的企业开始依赖云计算技术来推动业务发展。其中,腾讯云和Cloudflare作为行业的佼佼者,吸引了广泛的关注。腾讯云是腾讯集团倾力打造的云计算品牌,凭借强大的技术背景和丰富的产品线,逐渐成为全球知名的云计算服务商。它的基础设施覆盖全球五大洲,运营于58个可用区,能够为不...

    Windows SSH Keygen 无法连接问题解决指南

    在现代网络环境中,SSH(Secure Shell)协议扮演着至关重要的角色,确保了远程登录的安全性与可靠性。在Windows操作系统中,了解SSH的基本知识是非常必要的。SSH不仅提供了加密的网络服务,还为我们在远程管理服务器时提供了安全的通道。 当我们谈到SSH的时候,首先想到的就是它的密钥认证...