博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式——代理模式
阅读量:6088 次
发布时间:2019-06-20

本文共 3792 字,大约阅读时间需要 12 分钟。

知识点:静态代理和动态代理

参考博客:https://www.cnblogs.com/daniels/p/8242592.html

                  https://blog.csdn.net/familyshizhouna/article/details/78905997

一:什么是代理模式

代理模式是给某个对象提供一个代理对象,由代理对象调用原对象的方法,类似我们生活中的中介,经纪人的角色,本人不直接去做,找一个人代替我们去做一些事情。

二:使用代理模式的好处

a.中介隔离作用:当我们不想直接调用一个对象时,代理对象可以起一个中介隔离的作用,被代理对象和代理对象都实现相同的接口

b.遵循开闭原则:我们可以通过代理类,在被代理类功能前后,加入一些公共服务,比如缓存,日志等,而不用修改原被代理类

三:代理模式的分类

 按创建代理的时间分类可以分为:静态代理和动态代理

   静态代理是代码创建后编译,运行之前,代理类的.class文件就已经创建了;

  动态代理:是在程序运行时,通过反射机制动态创建代理对象的(另一篇博客简略地介绍Java中的反射:https://www.cnblogs.com/shuaifing/p/10863645.html)

(1)静态代理

//代理模式(静态代理) //测试类 public class StaticProxy {
public static void main(String[] args) {
Object obj=new ProxyObject(); obj.action(); } } //公共接口 interface Object{
void action(); } //代理类 class ProxyObject implements Object{ Object obj; public ProxyObject(){ System.out.println("代理类构造方法创建被代理类"); obj=new ObjectImp(); } @Override public void action() { System.out.println("代理类执行被代理类中的方法"); obj.action(); } } //被代理类 class ObjectImp implements Object{ @Override public void action() { System.out.println("被代理类输出的内容!"); } } 运行结果:

(2)动态代理

当有多个类要代理的话,手动创建多个代理对象比较麻烦,代码冗余,动态产生代理对象的话,代码更加灵活,方便

//动态代理,反射是动态语言的关键 //测试类 public class DynamicProxy {
public static void main(String[] args) {
//1.被代理类的对象 RealSubject realSubject=new RealSubject(); //2.创建一个实现InvocationHandler接口类的对象 MyInvocationHandler handler=new MyInvocationHandler(); //3.调用blind()方法,动态返回一个实现了跟被代理类所实现接口的代理对象 Object obj=handler.blind(realSubject); Subject subject=(Subject) obj;//subject是代理类对象 subject.action();//代理类对象调用action(),会转到对InvocationHandler接口实现类的invoke()方法调用 //增加另一个 ObjectImp的被代理对象,返回相应的代理对象 ObjectImp objIml=new ObjectImp(); com.kdgc.interfacetest.Object proxyObject= (com.kdgc.interfacetest.Object)handler.blind(objIml); proxyObject.action(); } } //公共接口 interface Subject{ void action(); } //被代理类 class RealSubject implements Subject{ @Override public void action() { System.out.println("被代理类要执行的方法!"); } } class MyInvocationHandler implements InvocationHandler{ Object obj;//实现了接口的被代理对象的声明 //1.给被代理对象实例化 2.返回一个代理类的对象 public Object blind(Object obj){ this.obj=obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this); } //当通过代理类的对象发起对被重写方法的调用时,会转化为对下面的invoke方法的调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object val=method.invoke(obj,args); return val; } } 运行结果:

 (3)补充:动态代理与AOP

在固定的代码的位置,动态地调用不同对象的方法

   //测试类

public class AOPTest {
public static void main(String[] args) {
Man man = new Man(); Person person = (Person) MyProxy.getProxyInstance(man); person.drink(); person.eat(); } } //公共接口 interface Person{
void eat(); void drink(); } //被代理类 class Man implements Person{ @Override public void eat() { System.out.println("吃东西!"); } @Override public void drink() { System.out.println("喝水!"); } } //固定的方法 class ChangelessMethodUtil{ public void method1(){ System.out.println("===========方法1=========="); } public void method2(){ System.out.println("============方法2==========="); } } class MyInvocationHanlder implements InvocationHandler{ Object obj;//代理类的声明 public void setObject(Object obj){ this.obj=obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ChangelessMethodUtil changelessMethodUtil=new ChangelessMethodUtil(); changelessMethodUtil.method1(); method.invoke(obj,args); changelessMethodUtil.method2(); return null; } } class MyProxy{ //动态创建一个代理类的对象 public static Object getProxyInstance(Object obj){ MyInvocationHanlder hanlder=new MyInvocationHanlder(); hanlder.setObject(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),hanlder); } }

运行结果:

转载于:https://www.cnblogs.com/shuaifing/p/10862633.html

你可能感兴趣的文章
阿里云公共镜像、自定义镜像、共享镜像和镜像市场的区别 ...
查看>>
shadowtunnel v1.7 发布:新增上级负载均衡支持独立密码
查看>>
Java线程:什么是线程
查看>>
mysql5.7 创建一个超级管理员
查看>>
【框架整合】Maven-SpringMVC3.X+Spring3.X+MyBatis3-日志、JSON解析、表关联查询等均已配置好...
查看>>
要想成为高级Java程序员需要具备哪些知识呢?
查看>>
带着问题去学习--Nginx配置解析(一)
查看>>
onix-文件系统
查看>>
java.io.Serializable浅析
查看>>
我的友情链接
查看>>
多线程之线程池任务管理通用模板
查看>>
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>
某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
查看>>
BABOK - 企业分析(Enterprise Analysis)概要
查看>>
Linux 配置vnc,开启linux远程桌面
查看>>