今天要介绍的是一个Java中一个很重要的概念——代理。
什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人作为中间人,负责代理明星的相关事宜,比如说,有人要请明星去唱歌表演,一般不会直接跟明星联系,而是联系他的经纪人,他的经纪人来负责安排行程,而真正唱歌表演的还是明星本人,经纪人仅仅作为一个附加物存在。
在Java中,代理也是这样的概念,来看个栗子:
先来创建一个明星类Stars:
public class Stars implements IStars{ private String name; public Stars(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void sing(){ System.out.println(getName() + " 唱了一首歌."); } public void dance(){ System.out.println(getName() + " 跳了一支舞."); } }
这是相应的接口:
public interface IStars { void sing(); void dance(); }
现在创建一个代理类:
public class StarsProxy implements IStars{ //保存接收的代理对象 private IStars stars; public StarsProxy(IStars stars){ this.stars = stars; } @Override public void sing() { System.out.println("我是代理,我收到了唱歌请求。"); stars.sing(); System.out.println("唱歌完毕"); } @Override public void dance() { System.out.println("我是代理,我收到了跳舞请求。"); stars.dance(); System.out.println("跳舞完毕"); } }
来测试一下:
public class Test { public static void main(String[] args){ //创建目标对象 IStars stars = new Stars("Frank");//代理对象,把目标传给代理对象,建立关系 IStars starsProxy = new StarsProxy(stars); starsProxy.sing(); starsProxy.dance(); } }
运行结果:
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了跳舞请求。
Frank 跳了一支舞.
跳舞完毕
我们可以看到,实际上代理类只是保存了Stars类的一个实例,因为实现的是相同的接口,StarsProxy类必须实现需要代理的Stars类的方法,比如这里的dance和sing,而这个接口正是链接两者的关键,因为实现接口就代表必定存在接口中声明的方法。
那么,为什么要使用代理呢?
其实主要目的是为了扩展原有类的功能,想想看,如果那个Stars类不是你写的,而是别人写的,现在要将原有的sing或者dance方法进行改造,比如需要统计唱歌和跳舞的次数,次数大于10则不进行该操作直接返回,这时候用代理就很好实现了,来把代理类稍作修改:
public class StarsProxy implements IStars{ //保存接收的代理对象 private IStars stars; //保存sing和dance的次数 private int num; public StarsProxy(IStars stars){ this.stars = stars; } @Override public void sing() { if (!ifWork()) { return; } System.out.println("我是代理,我收到了唱歌请求。"); stars.sing(); System.out.println("唱歌完毕"); } @Override public void dance() { if (!ifWork()) { return; } System.out.println("我是代理,我收到了跳舞请求。"); stars.dance(); System.out.println("跳舞完毕"); } /** * 是否继续工作 * @return 是返回true,否则返回false */ private boolean ifWork(){ if (num > 3){ System.out.println("明星今天已经很累了,明天再来吧。"); return false; }else { num++; return true; } } }
修改一下测试类:
public class Test { public static void main(String[] args){ //创建目标对象 Stars stars = new Stars(); stars.setName("Frank"); //代理对象,把目标传给代理对象,建立关系 StarsProxy starsProxy = new StarsProxy(stars); for (int i = 0;i < 5; i++){ starsProxy.sing(); } } }
测试结果如下:
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
明星今天已经很累了,明天再来吧。
看,简单粗暴。
但其实并没有多少干货,这里仅仅是一种代理的思想,用这种思想可以比较方便的在不直接修改原有类的前提下对原有类的方法进行扩展。为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。可以使业务类只关注业务逻辑本身,保证了业务类的重用性,这也是代理的共有优点。
但是限制也显而易见:
1.代理类需要跟被代理类实现相同的接口,这样才能一起向上转型后实现多态。
2.当被代理的类需要进行的扩展增多时,管理会变得更加困难,之后对被代理类的修改,需要同时修改代理类,增加了修改成本。
所以不要为了使用而使用,应用在合适的场景才能发挥它真正的作用。
至此,本篇讲解完毕,欢迎大家继续关注!
以上就是详解 Java静态代理的详细内容,更多关于Java静态代理的资料请关注小牛知识库其它相关文章!
本文向大家介绍详解Java JDK动态代理,包括了详解Java JDK动态代理的使用技巧和注意事项,需要的朋友参考一下 今天来看看Java的另一种代理方式——JDK动态代理 我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象。动态代理有更强大的拦截请求功能,因为可以获得类的运行时信息,可以根据运行时信息来获得更为强大的执(骚)行(操)力(作)。
本文向大家介绍Java静态static关键字原理详解,包括了Java静态static关键字原理详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java静态static关键字原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 static关键字既可以修饰成员变量,也可以修改成员方法,修饰的成员变量和成员方法可以直接通过类名调用,
本文向大家介绍Java中的静态内部类详解及代码示例,包括了Java中的静态内部类详解及代码示例的使用技巧和注意事项,需要的朋友参考一下 1. 什么是静态内部类 在Java中有静态代码块、静态变量、静态方法,当然也有静态类,但Java中的静态类只能是Java的内部类,也称为静态嵌套类。静态内部类的定义如下: 在介绍静态内部类之前,首先要弄清楚静态内部类与Java其它内部类的区别。 2. 内部类 什么
本文向大家介绍java Freemarker页面静态化实例详解,包括了java Freemarker页面静态化实例详解的使用技巧和注意事项,需要的朋友参考一下 Freemarker FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与 Web 容器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP。它不仅可以用作表现层
本文向大家介绍PHP页面静态化——纯静态与伪静态用法详解,包括了PHP页面静态化——纯静态与伪静态用法详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP页面静态化——纯静态与伪静态用法。分享给大家供大家参考,具体如下: 为什么要静态化页面? 当用户访问一个不经常更新的Web页面,PHP接到指示对php脚本文件进行解析,从数据库查询到该页面所需要的数据,然后对页面模板进
本文向大家介绍Java静态代理和动态代理总结,包括了Java静态代理和动态代理总结的使用技巧和注意事项,需要的朋友参考一下 静态代理 第一种实现(基于接口): 1》接口 2》目标类,至少实现一个接口 3》代理类(与目标类实现相同接口,从而保证功能一致) 3》测试 第二种实现(基于目标类): 1>目标类 2>代理类(通过继承目标类,保证功能一致) 3>测试 动态代理 动态代理的代理类是在程序运行期间