Java - 静态代理详讲

作者 : Stanley 罗昊

转载请注明出处和署名,谢谢!

写在前面:*此章内容比较抽象,所以需要结合实际操作进行讲解*

                  *需要有一定的java面向对象基础*

静态代理的实现步骤(举例说明)

首先,我们需要建立一个java工程来实现一个例子,从而理解什么是java中的静态代理;

建好项目后,我们需要在项目中新建一个包,然后在包下建一个接口,人的接口(Person),紧接着呢,我们在接口中创建一个吃饭的方法:

这个方法就被称之为抽象方法,接下来呢,我将会去写一个实现类,它们分别是,老师(Teacher)实现类,紧接着,我们需要让这个类实现Person这个接口并实现Person类中定义好的抽象方法

并且在改方法中输出一句话,来表示这个方法的所执行的意义;

接下来呢,我再定义一个学生(Student)类,并全也去实现人类(Person),并且实现该类中的方法:

以上都创建完毕之后呢,我们来建立一个测试类,将Student类实例化,调用学生吃零食这个方法:

打印结果就是 学生在吃零食。。。。。;

同样的,我们将老师类也在测试类中实例化,并且调用老师吃饭方法,那么打印结果就是:

学生在吃零食。。。。。。

老师在吃饭。。。。。。

需求增强

完成以上步骤之后呢,现在我们的需求突然要求增强;

需求变化:无论是老师还是学生,我都需要让他们在吃饭之前先跑一圈,吃饭之后,再去跑一圈;

我们的需求发生了这样的一个变化,你该如何实现呢?下面我列出几个实现的策略:

1.修改原始代码的实现

这个就很好实现,比如,我现在要把学生类根据以上要求增强,我们只需要去实现类中修改原方法即可:

现在,我们再运行Test这个类看效果:

这种结果,是不是就是根据以上需求进行增强了;

注:但是,这种方式,非常不提倡使用,因为,实际开发中一般不会去修改以及提交的代码,

因为你提交完成之后,别的小组就会调用你的这行代码,所以,在实际开发当中,我们不会轻易的去修改原始代码;

2.可以找一个代理

代理主要作用:

来做一些需要增强的事情;

举例:这个代理,就类似于,明星的经纪人。

我们假设现在有一个演员王宝强,王宝强的经纪人是谁啊----------宋喆对吧;

王宝强最早出道的时候仅仅是一个小演员,小演员的时候,没有经纪人,所以他只负责跑龙套就行了,跑龙套对他来说是完全可以应付过来的,但是随着他越来越火,他已经不是演戏那么简单了,他除了演戏,他还需要拍广告、还需要宣传,这些都需要他干对把,

演戏是不是需要他一个人去接戏啊,接广告的话,是不是还需要去谈这个广告啊,如果他只身一人的话,他还需要去接戏、接广告、接宣传,因为考虑到他经历有限,是不是这些工作他一个人是无法独自完成的;

这个时候呢,王宝强就想到了一个办法,请一个代理,也就是我们所谓的经纪人;

经纪人干的活就是王宝强可以不亲自去干的活,而王宝强的核心业务是不是仅仅的去拍戏即可,一个经纪人可以有经纪多个演员

代理模式

代理

这个代理,是不是就类似于上面我所述的经纪人

被代理

被代理,是不是就是王宝强

静态代理

刚才,我们用了第一种方式来实现了对需求进行了增强,很显然,这样做是不对的,在实际开发中,企业里也不允许这样去做,所以我们把刚才写的那几句打印输出语句给删掉;

那,接下来就改变一下需求:

学生在吃饭之前,需要买饭,吃完饭后需要扔垃圾

从以上需求,我们大概能分析出来,吃饭是学生的核心,然而扔垃圾、买饭,是不是就是找一个经纪人就行了;

所以接下来,我们就给学生找一个代理;

1.首先,我们需要建一个类(ProxyStudent)

2.那么ProxyStudent既然是学生的代理类,那么就必须要有跟学生一样的功能,另外辅助的功能后续再添加;

刚才学生类实现了一个接口(Person),那么它的代理类,也必须要去实现Person,吃饭的方法实际上还是学生在做,

这里的核心功能依然是学生自己的,底层调用的还是学生自己的,也就是在我的这个代理对象中的吃饭这个方法里面你必须去调用学生的;

既然需要在代理对象中,需要去调用学生吃饭的方法,那这个代理对象(ProxyStudent)的代理类中,是不是就需要有学生的属性:

如果直接使用s.,执行必然是空指针异常,所以,我们需要给这个学生对象使用构造器进行初始化;

那么接下来,我们再需要进行增强,我们是不是仅需要在s.chifan();方法前后添加就行啦;

这样以来,是不是就是对原始的方法进行了一次增强;

接下来,我再写一个测试类(ProxyTest),进行测试;

那么在测试类中,我们仅需要调用代理对象即可,也就是说直接找宋喆,别再去找王宝强了,就是这样意思.....

实例化代理对象之后,我是不是就可以通过代理对象去调用我的吃饭方法啦;

来看下执行结果:

是不是代理帮我买大餐,我只负责吃饭,代理帮我扔垃圾;

那么通过这样的一个手段就实现了一个代理;

静态代理分析

那么,在以上的这个代理类中,真正的核心方法还是被代理对象的,你这个吃饭的这个核心方法是不是就是吃零食啊;

学生正在吃零食是不是就是调用学生的,另外两个是我自己拓展加上去的对吧;

而其他的辅助的方法,是不是就算是代理去做了;

代理模式的编写要点

1.和被代理对象实现相同的接口

2.在代理类中,需要对被代理对象初始化

3.需要实现和被dialing对象相同的方法,并且在这个方法中核心(原始)业务调用被代理对象的,增强的业务在这里进行增强就行了

静态代理方式的弊端

静态代理方式是有缺陷的;

1.如果有很多个对象需要找代理,那么就需要实现很多个对象的代理类,这样的话代码臃肿,用户体验很一般;

2.如果被代理的方法过多,每个方法都需要增强,代码不整洁,大量搬用的工作

它有这两大缺陷就造成了写大型项目的时候,就不会用静态代理这个设计模式

Java - 静态代理详讲的更多相关文章

  1. java:java静态代理与动态代理简单分析

    java静态代理与动态代理简单分析 转载自:http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动 ...

  2. Java静态代理&动态代理&Cglib代理详解

    一.静态代理 根据被代理的类的时机的不同,如果在编译阶段就能确定下来的被代理的类是哪一个,那么,就可以使用静态代理的方式. 申明一个接口: /** * @author jiaqing.xu@hand- ...

  3. java静态代理,动态代理,cglib代理

    代理模式在我们的应用中是很常见的,例如拦截器,spring的事务管理等.之所以能被代理,是因为java允许我们通过反射机制动态构造目标对象,并调用相应的方法. 就好像拿到了目标对象的引用,自然可以在目 ...

  4. Java静态代理与动态代理模式的实现

    前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...

  5. java 静态代理 JDK动态代理 Cglib动态代理

    下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行 ...

  6. JAVA静态代理和动态代理理解

    代理 代理是英文 Proxy 翻译过来的.我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了. 她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人. 按理说,顾客可以直接从厂家购买产品,但 ...

  7. java静态代理与动态代理

    原文链接:http://www.orlion.ga/207/ 一.代理模式 代理模式是经常用到的设计模式,代理模式是给指定对象提供代理对象.由代理对象来控制具体对象的引用. 代理模式涉及到的角色: 抽 ...

  8. JAVA静态代理模式(从现实生活角度理解代码原理)

    代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 代理模式说白了就是"真实对象"的代表,在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途. 在 ...

  9. java静态代理与动态代理简单分析

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理 ...

随机推荐

  1. Mybatis批量更新数据库与批量插入数据库(以oracle为例)

    一.批量更新 1.普通写法(一条记录update一次,性能比较差,容易造成阻塞.不建议使用) <update id="updateBatch" parameterType=& ...

  2. 架构之微服务(zookeeper)

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...

  3. C#System.Text.RegularExpressions.Regex使用(二) .

    (6)特殊字符的匹配 string x = "//"; Regex r1 = new Regex("^////$"); Console.WriteLine(&q ...

  4. python while 循环语句

    Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件: 执行语句-- 执行语句可以是单个语句或语句 ...

  5. wordpress上下篇

    分页一: <!--上下篇开始--> <div class="shangxia"> <?php $current_category=get_the_ca ...

  6. vue项目中解决type=”file“ change事件只执行一次的问题

    问题描述 在最近的项目开发中遇到了这样的一个问题,当我上传了一个文件时,我将获取到的文件名清空后,却无法再次上传相同的文件 <template> <div class="h ...

  7. 并发库应用之九 & 到时计数器CountDownLatch应用

    申明:CountDownLatch好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurre ...

  8. JAVA线程池shutdown和shutdownNow的区别

    一.区别介绍 shutDown()  当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态.此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionExcept ...

  9. 使用libpcap过滤arp

    上一篇博客简单讲述了libpcap的工作流程及简单使用,今天我们需要做的是继续使用libpcap抓取我们感兴趣的流量,并进行简单的解析: 测试环境是centos 7 下面贴一张arp帧结构图: 下面我 ...

  10. Linux内核编程、调试技巧小集

    1. 内核中通过lookup_symbol_name获取函数名称 内核中很多结构体成员是函数,有时可能比较复杂不知道具体使用哪一个函数.这是可以通过lookup_symbol_name来获取符号表名称 ...