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

【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理java proxy 动态代理

7小时前CN2资讯


这篇博文,我们主要以类图和代码的形式来对比学习一下静态代理和动态代理,重点解析各自的优缺点。


定义


       代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用。


       代理模式不会改变原来的接口和行为,只是转由代理干某件事,代理可以控制原来的目标,例如:代理商,代理商只会买东西,但并不会改变行为,不会制造东西。让我们通过下面的代码好好理解一下这句话。


分类


静态代理和动态代理


静态代理


静态代理类图

                


代码示例

     


接口

package com.liang.pattern; public interface UserManager { public void addUser(String userId,String userName); public void delUser(String userId); public void modifyUser(String userId,String userName); public String findUser(String userId); }
目标对象 package com.liang.pattern; public class UserManagerImpl implements UserManager { public void addUser(String userId, String userName) { try{ System.out.println("UserManagerImpl.addUser() userId-->>" + userId); }catch(Exception e){ e.printStackTrace(); throw new RuntimeException(); } } public void delUser(String userId) { System.out.println("UserManagerImpl.delUser() userId-->>" + userId); } public String findUser(String userId) { System.out.println("UserManagerImpl.findUser() userId-->>" + userId); return "于亮"; } public void modifyUser(String userId, String userName) { System.out.println("UserManagerImpl.modifyUser() userId-->>" + userId); } }
代理类,我们使用代理对象做一些日志记录,我们将简略的信息打印到控制台。 package com.liang.pattern; public class UserManagerImplProxy implements UserManager { private UserManager userManager; public UserManagerImplProxy(UserManager userManager){ this.userManager = userManager; } public void addUser(String userId, String userName) { //记录日志等操作或打印输入参数 System.out.println("start-->>addUser() userId-->>" + userId); try{ userManager.addUser(userId, userName); //执行成功,打印成功信息 System.out.println("success-->>addUser()"); }catch(Exception e){ e.printStackTrace(); //失败时,打印失败信息 System.out.println("error-->>addUser()"); //throw new RuntimeException(); } } public void delUser(String userId) { //同上,略 userManager.delUser(userId); } public String findUser(String userId) { //同上,略 userManager.findUser(userId); return null; } public void modifyUser(String userId, String userName) { //同上,略 userManager.modifyUser(userId, userName); } }
客户端调用 package com.liang.pattern; public class Client { /** * @param args */ public static void main(String[] args) { UserManager userManager = new UserManagerImplProxy(new UserManagerImpl()); userManager.addUser("001","于亮"); } }
输出结果,此方法执行成功 start-->>addUser() userId-->>001 UserManagerImpl.addUser() userId-->>001 success-->>addUser()
       从类图我们可以看出,客户端本来可以直接和目标对象打交道,代理中间加了一个间接层,他们实现的功能是一样的,也没有改变参数。相信大家对上面的类图和代码很熟悉,跟我们平时看别人的博文一样,没有任何区别,下面我们看一下静态代理的优缺点。


优缺点


优点

1、直观感受,静态代理是实实在在的存在的,我们自己写的。

2、在编译期加入,提前就指定好了谁调用谁,效率高。


缺点

同样,它的优点也成了它致命的缺点。

1、静态代理很麻烦,需要大量的代理类

     当我们有多个目标对象需要代理时,我就需要建立多个代理类,改变原有的代码,改的多了就很有可能出问题,必须要重新测试。

2、重复的代码会出现在各个角落里,违背了一个原则:重复不是好味道

      我们应该杜绝一次次的重复。

3、在编译期加入,系统的灵活性差



       我们可以看到代理类的每个方法中,都有记录日志,执行成功或失败的代码,每个方法都重复了一遍,如果我们需要修改的话,并没有比不用静态代理时减少修改的地方,只是不用修改目标类。动态代理很好的为我们解决了这个问题,下面我们看一下动态代理。


动态代理


动态代理类图


               


代码示例



代理类(不明白,就看看注释吧)

package com.liang.pattern; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 采用JDK动态代理必须实现InvocationHandler接口,采用Proxy类创建相应的代理类 * @author liang * */ public class ProxyHandler implements InvocationHandler { private Object targetObject; /** * 目标的初始化方法,根据目标生成代理类 * @param targetObject * @return */ public Object newProxyInstance(Object targetObject){ this.targetObject = targetObject; //第一个参数,目标的装载器 //第二个参数,目标接口,为每个接口生成代理 //第三个参数,调用实现了InvocationHandler的对象,当你一调用代理,代理就会调用InvocationHandler的invoke方法 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } /** * 反射,这样你可以在不知道具体的类的情况下,根据配置的参数去调用一个类的方法。在灵活编程的时候非常有用。 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //记录日志等操作或打印输入参数 System.out.println("start-->>" + method.getName()); for(int i=0;i<args.length;i++){ //打印调用目标方法的参数 System.out.println(args[i]); } Object ret = null; try{ //调用目标方法 ret = method.invoke(targetObject, args); //执行成功,打印成功信息 System.out.println("success-->>" + method.getName()); }catch(Exception e){ e.printStackTrace(); //失败时,打印失败信息 System.out.println("error-->>" + method.getName()); throw e; } return ret; } }
客户端调用 package com.liang.pattern; public class Client { /** * @param args */ public static void main(String[] args) { ProxyHandler proxyHandler = new ProxyHandler(); UserManager userManager = (UserManager)proxyHandler.newProxyInstance(new UserManagerImpl()); String name = userManager.findUser("0001"); System.out.println("client.main-->>" + name); } }


输出结果,运行成功

start-->>findUser 0001 UserManagerImpl.findUser() userId-->>0001 success-->>findUser client.main-->>于亮

接口和目标类,同上,我就不再浪费大家的带宽了。


优缺点


优点

1、一个动态代理类更加简单了,可以解决创建多个静态代理的麻烦,避免不断的重复多余的代码

2、调用目标代码时,会在方法“运行时”动态的加入,决定你是什么类型,才调谁,灵活


缺点

1、系统灵活了,但是相比而言,效率降低了,比静态代理慢一点

2、动态代理比静态代理在代码的可读性上差了一点,不太容易理解

3、JDK动态代理只能对实现了接口的类进行代理


总结


       静态代理VS动态代理,打成了平手,各自有各的独特之处,均不可代替,在项目中到底使用哪种代理,没有最好,只有更合适。



    你可能想看:

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

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

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

    分享给朋友:

    “【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理java proxy 动态代理” 的相关文章

    CN2中转:提高数据传输效率的最佳选择

    CN2中转概述 当我第一次接触CN2中转时,我就被它的高效和可靠性所吸引。CN2中转是一种通过中国电信的CN2线路进行数据传输的方式。这条线路不仅仅是简单的网络连接,它被誉为“二类全业务”数据专线,能够提供高速、低时延、低抖动和低丢包率的优质网络服务。帮助用户更好地访问境外数据,这一点让我感到它的重...

    BuyVM色情网站托管服务解析 - 提升成人内容运营安全与效率

    什么是BuyVM色情服务 当我提到BuyVM的时候,可能很多人对这个名字还不太熟悉。简单来说,BuyVM是一家提供虚拟专用服务器(VPS)和网站托管服务的公司,专注于各种类型的内容,包括成人色情内容。它的历史可以追溯到多个年份前,BuyVM在业内逐渐赢得了声誉,成为不少成人网站的首选托管平台。以其可...

    搬瓦工VPS:初学者的最佳选择与使用指南

    大家对VPS可能不太熟悉,搬瓦工VPS在整个市场中已经站稳了脚跟。作为加拿大IT7公司旗下的一款主机服务,搬瓦工以其性价比高的OpenVZ VPS起步,而现在主要以KVM架构为主流,逐渐发展成为国内用户的热门选择。这种转型让我觉得很有意思,因为它不仅仅是一种产品的升级,更是一种服务的提升。 搬瓦工提...

    日本节点的重要性与旅行体验优化指南

    日本节点的定义与重要性 在数字化飞速发展的今天,网络成为了沟通和信息流通的主要渠道。这里提到的“节点”,其实是指网络中数据传输的关键环节,可以理解为互联网的一个重要接点。每一个节点都承担着流量的传输与分发,确保数据能够迅速而高效地在全球范围内流动。想象一下,网络就像一张巨大的蜘蛛网,各个节点犹如网中...

    腾讯云国际版:全球云服务的强者之选,满足您的业务需求

    腾讯云国际版概述 腾讯云国际版的定义与背景 腾讯云国际版是腾讯公司专为全球客户推出的一款云服务产品,旨在满足不同国家和地区用户的需求。它在功能上与国内版本相似,但根据国际市场的需求进行了优化,以确保服务的稳定性和流畅性。作为一名用户,我发现腾讯云国际版特别注重数据隐私和合规性,这对于希望拓展海外市场...

    中转机:提升航班灵活性与旅行体验的最佳选择

    中转机的基本定义 中转机,是在航空运输中大量使用的一种方式。简单来说,就是乘客在一段航程中需要在特定的中转站停留,然后再继续前往他们的最终目的地。这个过程中,乘客的航空器可能会更换,或者在中转站转机的时间不同。中转机的作用主要体现在提高航班的灵活性与覆盖范围上。 我想起了自己那次在国外旅行时的经历。...