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. POST与PUT

    POST和PUT都是HTTP中客户端向服务器发送请求的方法 POST : 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件).数据被包含在请求本文中.这个请求可能会创建新的 资源或修改 ...

  2. GitHub学习笔记:本地操作

    安装过程略,假设你已经注册好了Github, 已经有了一个准备好的程序.我们的一切工作都是基于Git Shell,与GUI客户端无关. 在使用前你先要配置好config中的几个内容,主要是你自己的个人 ...

  3. QT中正则表达式的简单说明

    使用方法: QRegExp acNumRE("[0-9]{19}"); lineEdit->setValidator(new QRegExpValidator(acNumRE ...

  4. bestcoder round 74 div2

    随便看了一场以前的bestcoder,然后顺便写了一下,都不码的样子 有中文题面,这里就不写题目大意了 T1. 刚开始想复杂了,T1可能是4道题里面想的最久的 我们大概弄一下就可以发现,如果a[i]& ...

  5. 学习CTF的经历-文件分析

    文件分析-ZIP伪加密 最近在准备铁人三项赛的比赛,所以在实验吧上尝试着学习CTF,目前菜鸡一枚 我主要负责的是Web和安全杂项这一块,安全杂项的知识点较为薄弱,在实验吧练习的过程中遇到一个很有趣的题 ...

  6. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (二)

    上次讲解了FairyGUI的最简单的热更新办法,并对其中一个Demo进行了修改并做成了热更新的方式. 这次我们来一个更加复杂一些的情况:Emoji. FairyGUI的   Example 04 - ...

  7. springboot+redis实现分布式session共享

    官方文档,它是spring session项目的redis相关的一个子文档:https://docs.spring.io/spring-session/docs/2.0.0.BUILD-SNAPSHO ...

  8. SSM-MyBatis-16:Mybatis中延迟加载

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 延迟加载: 所谓延迟加载是什么? 从字面意思理解到的是等一会再加载 从行为分析,他主要是缓解数据库压力,提高性 ...

  9. xinetd被动服务唤醒

    rsync设置: 1.打开rsync控制开关(修改文件 /etc/default/rsync)2.sudo cp /usr/share/doc/rsync/examples/rsyncd.conf / ...

  10. CentOS 7安装Python3.6过程(让linux系统共存Python2和Python3环境)

    CentOS 7系统自带了python2,不过可以不用2版本,直接使用python3运行python脚本就可以,但是千万别去动系统自带的python2,因为有程序依赖目前的python2环境,比如yu ...